2009-10-13 25 views
1

在我的程序中,我從串口設備(Linux,8N1)讀取沒有任何問題。但是在我想寫出一個字節的情況下,我沒有在界面上看到任何東西。我假設我的串行輸出設置是錯誤的。但有沒有那麼多的方式如何設置c_oflag定義...串行設備:讀取8N1的作品,但寫入一個字節失敗

我的代碼:

#define TTYDEVICE "/dev/ttyS0" 
#define BAUDRATE B9600 

int openSerialDevice(const char* devTTY, struct termios oldTio) { 
//----< Open serial device >---------------------------------- 
int fileDescriptor; 
// fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); 
fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY); 
//fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY /*| OPOST*/); 
if (fileDescriptor == -1) { 
    perror("Error while opening serial interface occurred!"); 
    return -99; 
} 

// set new parameters to the serial device 
struct termios newtio; 
bzero(&newtio, sizeof(newtio)); 
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; 

// set to 8N1 
newtio.c_cflag &= ~PARENB; 
newtio.c_cflag &= ~CSTOPB; 
newtio.c_cflag &= ~CSIZE; 
newtio.c_cflag |= CS8; 

newtio.c_iflag = IGNPAR; 

// output mode to 
//newtio.c_oflag = 0; 
newtio.c_oflag |= OPOST; 

/* set input mode (non-canonical, no echo,...) */ 
newtio.c_lflag = 0; 

newtio.c_cc[VTIME] = 10; /* inter-character timer 1 sec */ 
newtio.c_cc[VMIN] = 0; /* blocking read disabled */ 

tcflush(fileDescriptor, TCIFLUSH); 
if (tcsetattr(fileDescriptor, TCSANOW, &newtio)) { 
    perror("could not set the serial settings!"); 
    return -99; 
} 

//----</Open serial device >---------------------------------- 
return fileDescriptor; 
} 

int ACK[1] = { 6 }; 

int main() { 
// old termios to restablish 
struct termios oldTIO; 
// filedescriptor 
int fd; 

fd = openSerialDevice(TTYDEVICE, oldTIO); 

if ((fd == -1) | (fd == -99)) { 
    perror("Could not open TTY-Device. Exit on failure!"); 
    return EXIT_FAILURE; 
} 

write(fd, ACK, 1); // Problem !! 


    return 0: 
} 

現在,如果我用

屏幕的/ dev/9600就是ttyS1 8N1

來驗證/ dev/ttyS0上出現的內容。我什麼也看不見。如果我使用Docklight 1.8進行嗅探,那也是一樣。

有什麼建議嗎?謝謝

回答

2

你如何驗證什麼都沒有出來?

您可以嘗試刪除RTSCTS,然後重試。逸岸,如果你想從tty層的干擾最小,您應將終端設置爲原料,採用這樣的:

cfmakeraw(&newtio); 
+0

同意。 RTSCTS表示硬件握手,通常不用於9600n81。這隻有在線路也由櫃檯部分觸發時纔有效。在硬件中連接RTS和CTS也應該使相同的程序工作,或者用適當的(空調制解調器)電纜將它連接到另一臺PC,並記得在那裏配置RTS/CTS握手。 – Adriaan 2009-10-13 14:08:22

2

你給write()ACK數據的說法,這是一個指向int。這可能不是你的意思。根據您所在電腦的endianness,這意味着write()將「看到」包含字符{ 6, 0, 0, 0 }(little-endian)或{ 0, 0, 0, 6 }(big-endian)的緩衝區。這假設sizeof (int) == 4是真實的,根據需要調整其他大小,問題依然存在。

您應該很有可能改爲使用緩衝區unsigned char。此外,如果您撥打了這樣的電話:

int wrote = write(fd, ACK, sizeof ACK); 
printf("Wrote %d bytes\n", wrote); 

您會得到直接的反饋。你應該測試這樣的東西,看看寫入是否成功。

0

激活的硬件流控制(CRTSCTS)是write()被阻塞的原因,並且最終在串行輸出中沒有出現任何內容。

謝謝!

代碼卡,其工作原理:

int openSerialDevice(const char* devTTY, struct termios oldTio) { 

    //----< Open serial device >---------------------------------- 
    int fileDescriptor; 
    // fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); 
    fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY); 
    //fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY /*| OPOST*/); 
    if (fileDescriptor == -1) { 
     perror("Error while opening serial interface occurred!"); 
     return -99; 
    } 

    // set new parameters to the serial device 
    struct termios newtio; 

    fcntl(fileDescriptor, F_SETFL, 0); 
    // set everything to 0 
    bzero(&newtio, sizeof(newtio)); 

    // again set everything to 0 
    bzero(&newtio, sizeof(newtio)); 

    newtio.c_cflag |= BAUDRATE; // Set Baudrate first time 
    newtio.c_cflag |= CLOCAL; // Local line - do not change "owner" of port 
    newtio.c_cflag |= CREAD; // Enable receiver 

    newtio.c_cflag &= ~ECHO; // Disable echoing of input characters 
    newtio.c_cflag &= ~ECHOE; 

    // set to 8N1 
    newtio.c_cflag &= ~PARENB; // no parentybyte 
    newtio.c_cflag &= ~CSTOPB; // 1 stop bit 
    newtio.c_cflag &= ~CSIZE; // Mask the character size bits 
    newtio.c_cflag |= CS8; // 8 data bits 

    // output mode to 
    newtio.c_oflag = 0; 
    //newtio.c_oflag |= OPOST; 


    // Set teh baudrate for sure 
    cfsetispeed(&newtio, BAUDRATE); 
    cfsetospeed(&newtio, BAUDRATE); 

    newtio.c_cc[VTIME] = 10; /* inter-character timer */ 
    newtio.c_cc[VMIN] = 0; /* blocking read until */ 

    tcflush(fileDescriptor, TCIFLUSH); // flush pending data 

    // set the new defined settings 
    if (tcsetattr(fileDescriptor, TCSANOW, &newtio)) { 
     perror("could not set the serial settings!"); 
     return -99; 
    } 

    //----</Open serial device >---------------------------------- 
    return fileDescriptor; 
}