[英]Programming Linux serial port, ttyS0
我正在嘗試學習如何使用C對Linux中的ttyS0串口進行編程。我的另一台機器連接到我的串口,大約每兩秒發送5f和6f的交替十六進制值。 我已經與其他端口監控應用程序驗證了這些值是否出現在端口上。 在我的代碼中,我使用阻塞read()到10個字符長度的緩沖區中。 即使我的其他機器仍在發送數據, read()也會永久阻止。 如果我包含行fcntl(fd,F_SETFL,FNDELAY); 將read()設置為非阻塞read()始終返回值為-1,這意味着UART緩沖區中沒有數據,而我的for循環代碼只打印出緩沖區中的隨機值。 所以簡而言之,我的假設是我的代碼不是讀取ttyS0而我不知道為什么。 下面是我的代碼,希望有人會看到是什么導致了我的問題並讓我直截了當。 順便說一句,我正在使用Scientific Linux,我相信ttyS0是com端口1,就像在RedHat和Fedora中一樣。 以下是我運行代碼時的輸出。 它似乎是寫入COM端口沒有問題,但對於讀取它說它不可用。 另外很明顯,我打印出的緩沖區只是隨機值,而不是已讀入的數據。謝謝
hello world
hi again
write error: : Success
wrote 4 bytes
number of bytes read is -1
read error:: Resource temporarily unavailable
4 8 120 -99 -73 -65 41 -120 4 8
should of put something out
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
int main()
{
printf("hello world\n");
int n;
int fd;
char c;
int bytes;
char buffer[10];
char *bufptr;
int nbytes;
int tries;
int x;
struct termios options;
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if(fd == -1)
{
perror("open_port: Unable to open:");
}
else
{
fcntl(fd, F_SETFL, 0);
printf("hi again\n");
}
tcgetattr(fd, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~( ICANON | ECHO | ECHOE |ISIG );
options.c_iflag &= ~(IXON | IXOFF | IXANY );
options.c_oflag &= ~OPOST;
tcsetattr(fd, TCSANOW, &options);
write(fd, "ATZ\r",4);
printf(" wrote\n");
bufptr = buffer;
fcntl(fd, F_SETFL, FNDELAY);
bytes = read(fd, bufptr, sizeof(buffer));
printf("number of bytes read is %d\n", bytes);
perror ("read error:");
for (x = 0; x < 10 ; x++)
{
c = buffer[x];
printf("%d ",c);
}
close(fd);
//puts(buffer[0]);
printf("\nshould of put something out \n");
return (0);
}
以下行將導致問題:
options.c_cflag &= CSTOPB;
它將重置c_cflag的所有其他位。
如果要使用1個停止位,則使用:
options.c_cflag &= ~CSTOPB;
如果要使用2個停止位,則使用:
options.c_cflag |= CSTOPB;
編輯:
以下行也會導致問題:
fcntl(fd, F_SETFL, 0);
它會重置幾個重要的標志。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.