2012-05-22 78 views
0

我想在我的串行端口上發送一個特定的字符串,並將答案讀入緩衝區以供進一步分析。我已經拿出了一些代碼,但即使是屏幕上的/dev/ttyUSB0 19200在shell上工作得很好,我也無法閱讀任何答案。 Decive需要8個數據位,1個起始位,1個停止位和無奇偶校驗。在19200波特。 現在我的代碼看起來是這樣的,是它讓timning出::(在Linux上的串行編程C

///////////////////////////////////////////////// 
// Serial port interface program    // 
///////////////////////////////////////////////// 
#include <stdio.h> // standard input/output functions 
#include <string.h> // string function definitions 
#include <unistd.h> // UNIX standard function definitions 
#include <fcntl.h> // File control definitions 
#include <errno.h> // Error number definitions 
#include <termios.h> // POSIX terminal control definitionss 
#include <time.h> // time calls 


int open_port(void) 
{ 
int fd; // file description for the serial port 

fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); 

if(fd == -1) // if open is unsucessful 
{ 
perror("open_port: Unable to open /dev/ttyUSB0"); 
} 
else 
{ 
fcntl(fd, F_SETFL, 0); 
} 

return(fd); 
} 

int configure_port(int fd)  // configure the port 
{ 
struct termios port_settings;  // structure to store the port settings in 

cfsetispeed(&port_settings, B19200); // set baud rates 
cfsetospeed(&port_settings, B19200); 

port_settings.c_cflag &= ~PARENB; // set no parity, stop bits, data bits 
port_settings.c_cflag &= ~CSTOPB; 
port_settings.c_cflag &= ~CSIZE; 
port_settings.c_cflag |= CS8; 

cfmakeraw(&port_settings); 
tcsetattr(fd, TCSANOW, &port_settings); // apply the settings to the port 
return(fd); 

} 

int query_modem(int fd) // query modem with an AT command 
{ 
int n; 
fd_set rdfs; 
struct timeval timeout; 
ssize_t retval; 
char bufptr[100]; 
char chr; 
int cnt = 0; 
int i = 0; 

// initialise the timeout structure 
timeout.tv_sec = 2; // ten second timeout 
timeout.tv_usec = 0; 

if (FD_ISSET(fd, &rdfs)){ 
    FD_ZERO(&rdfs); 
    FD_CLR(fd,&rdfs); 
} 

retval = write(fd, "TEST\r", 5); // send an AT command followed by a CR 
/*usleep(50); 
while (read(fd, &chr, 1)) 
{ 
printf("0x%x\n",chr); 
usleep(10); 
}*/ 

// do the select 
n = select(fd + 1, &rdfs, NULL, NULL, &timeout); 

// check if an error has occured 
if(n < 0) 
{ 
perror("select failed\n"); 
} 
else if (n == 0) 
{ 
printf("Timeout\n"); 
} 
else 
{ 
printf("\nBytes detected on the port!\n"); 
} 

} 

int main(void) 
{ 
int fd = open_port(); 
configure_port(fd); 
query_modem(fd); 
return(0); 
} 

什麼我希望後面是一個字符串說 「TEST」一樣在屏幕上時,我打進入 任何幫助將是不勝感激! 非常感謝你!

羅恩

+0

你FD_ISSSET()和FD_ZERO()和FD_CLR(的使用)是沒有意義的。您無條件地需要FD_ZERO()和FD_SET()。請參閱下面的@ ott--答案。 – wildplasser

回答

1

我的建議是,你還沒有加入FD到RFDS。檢查FD_ *宏清除一組,加FD,檢查是否有FD輸入。

更新

你真的需要到FD添加到fdset:當您選擇多個FD

write(... 
FD_ZERO(&rdfs); 
FD_SET(fd, &rfds); 
n = select(... 
if (n > 0) { 
    if (FD_ISSET(fd, &rfds)) { 
     // this fd has input waiting to be read 

n可以成爲> 1。

+0

我不明白,你是什麼意思「你沒有添加fd到rfds」?我如何設置fd?我不確定...請指教!謝謝! – cerr

+0

檢查FD_ZERO,FD_SET和FD_ISSET的選擇手冊('man 3 select')。 –

+0

好的,謝謝哦!我加了這個,但結果沒有真正改變。添加了以下幾行只是寫()之前: 如果(FD_ISSET(FD,與RDFS)){ FD_ZERO(&rdfs); FD_CLR(FD,&rdfs); } – cerr

0

簡單的C代碼

char types[25];  
char buffu[256]; 
int fd: 

strcat(types,"speed 115200 -parenb cs8 cstopb -ixon -ixoff -crtscts clocal cread raw"); 
fd=open("dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); 
ioctl(fd, F_SETFL, 0); 

..... 

write (fd, buffu, 255); 
usleep(400); 
read (fd,buffu,255);