之前基于IBM deveplopworks社区的代码,做了串口初始化和发送的程序,今天在此基础上添加了读取串口数据的程序。首先是最简单的循环读取程序,第二个是通过软中断方式,使用信号signal机制读取串口,这里需要注意的是硬件中断是设备驱动层级的,而读写串口是用户级行为,只能通过信号机制模拟中断,信号机制的发生和处理其实于硬件中断无异,第三个是通过select系统调用,在没有数据时阻塞进程,串口有数据需要读时唤醒进程。第二个和第三个例子都能用来后台读取数据,值得学习。
代码一:循环读取数据
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
-
#define FALSE -1
-
#define TRUE 0
-
-
int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,B38400, B19200, B9600, B4800, B2400, B1200, B300, };
-
int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, };
-
void set_speed(int fd, int speed){
-
int i;
-
int status;
-
struct termios Opt;
-
tcgetattr(fd, &Opt);
-
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {
-
if (speed == name_arr[i]) {
-
tcflush(fd, TCIOFLUSH);
-
cfsetispeed(&Opt, speed_arr[i]);
-
cfsetospeed(&Opt, speed_arr[i]);
-
status = tcsetattr(fd, TCSANOW, &Opt);
-
if (status != 0) {
-
perror("tcsetattr fd1");
-
return;
-
}
-
tcflush(fd,TCIOFLUSH);
-
}
-
}
-
}
-
-
int set_Parity(int fd,int databits,int stopbits,int parity)
-
{
-
struct termios options;
-
if ( tcgetattr( fd,&options) != 0) {
-
perror("SetupSerial 1");
-
return(FALSE);
-
}
-
options.c_cflag &= ~CSIZE;
-
switch (databits)
-
{
-
case 7:
-
options.c_cflag |= CS7;
-
break;
-
case 8:
-
options.c_cflag |= CS8;
-
break;
-
default:
-
fprintf(stderr,"Unsupported data size\n"); return (FALSE);
-
}
-
switch (parity)
-
{
-
case 'n':
-
case 'N':
-
options.c_cflag &= ~PARENB;
-
options.c_iflag &= ~INPCK;
-
break;
-
case 'o':
-
case 'O':
-
options.c_cflag |= (PARODD | PARENB);
-
options.c_iflag |= INPCK;
-
break;
-
case 'e':
-
case 'E':
-
options.c_cflag |= PARENB;
-
options.c_cflag &= ~PARODD;
-
options.c_iflag |= INPCK;
-
break;
-
case 'S':
-
case 's':
-
options.c_cflag &= ~PARENB;
-
options.c_cflag &= ~CSTOPB;break;
-
default:
-
fprintf(stderr,"Unsupported parity\n");
-
return (FALSE);
-
}
-
-
switch (stopbits)
-
{
-
case 1:
-
options.c_cflag &= ~CSTOPB;
-
break;
-
case 2:
-
options.c_cflag |= CSTOPB;
-
break;
-
default:
-
fprintf(stderr,"Unsupported stop bits\n");
-
return (FALSE);
-
}
-
-
if (parity != 'n')
-
options.c_iflag |= INPCK;
-
tcflush(fd,TCIFLUSH);
-
options.c_cc[VTIME] = 150;
-
options.c_cc[VMIN] = 0;
-
if (tcsetattr(fd,TCSANOW,&options) != 0)
-
{
-
perror("SetupSerial 3");
-
return (FALSE);
-
}
-
return (TRUE);
-
}
-
-
int main()
-
{
-
printf("This program updates last time at %s %s\n",__TIME__,__DATE__);
-
printf("STDIO COM1\n");
-
int fd;
-
fd = open("/dev/ttyS0",O_RDWR);
-
if(fd == -1)
-
{
-
perror("serialport error\n");
-
}
-
else
-
{
-
printf("open ");
-
printf("%s",ttyname(fd));
-
printf(" succesfully\n");
-
}
-
-
set_speed(fd,115200);
-
if (set_Parity(fd,8,1,'N') == FALSE) {
-
printf("Set Parity Error\n");
-
exit (0);
-
}
-
char buf[] = "fe55aa07bc010203040506073d";
-
write(fd,&buf,26);
-
char buff[512];
-
int nread;
-
while(1)
-
{
-
if((nread = read(fd, buff, 512))>0)
-
{
-
printf("\nLen: %d\n",nread);
-
buff[nread+1] = '\0';
-
printf("%s",buff);
-
}
-
}
-
close(fd);
-
return 0;
-
}
代码清单二:通过signal机制读取数据
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
-
#define FALSE -1
-
#define TRUE 0
-
#define flag 1
-
#define noflag 0
-
-
int wait_flag = noflag;
-
int STOP = 0;
-
int res;
-
-
int speed_arr[] =
-
{ B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,
-
B4800, B2400, B1200, B300, };
-
int name_arr[] =
-
{ 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400,
-
1200, 300, };
-
void
-
set_speed (int fd, int speed)
-
{
-
int i;
-
int status;
-
struct termios Opt;
-
tcgetattr (fd, &Opt);
-
for (i = 0; i < sizeof (speed_arr) / sizeof (int); i++)
-
{
-
if (speed == name_arr[i])
-
{
-
tcflush (fd, TCIOFLUSH);
-
cfsetispeed (&Opt, speed_arr[i]);
-
cfsetospeed (&Opt, speed_arr[i]);
-
status = tcsetattr (fd, TCSANOW, &Opt);
-
if (status != 0)
-
{
-
perror ("tcsetattr fd1");
-
return;
-
}
-
tcflush (fd, TCIOFLUSH);
-
}
-
}
-
}
-
-
int
-
set_Parity (int fd, int databits, int stopbits, int parity)
-
{
-
struct termios options;
-
if (tcgetattr (fd, &options) != 0)
-
{
-
perror ("SetupSerial 1");
-
return (FALSE);
-
}
-
options.c_cflag &= ~CSIZE;
-
switch (databits)
-
{
-
case 7:
-
options.c_cflag |= CS7;
-
break;
-
case 8:
-
options.c_cflag |= CS8;
-
break;
-
default:
-
fprintf (stderr, "Unsupported data size\n");
-
return (FALSE);
-
}
-
switch (parity)
-
{
-
case 'n':
-
case 'N':
-
options.c_cflag &= ~PARENB;
-
options.c_iflag &= ~INPCK;
-
break;
-
case 'o':
-
case 'O':
-
options.c_cflag |= (PARODD | PARENB);
-
options.c_iflag |= INPCK;
-
break;
-
case 'e':
-
case 'E':
-
options.c_cflag |= PARENB;
-
options.c_cflag &= ~PARODD;
-
options.c_iflag |= INPCK;
-
break;
-
case 'S':
-
case 's':
-
options.c_cflag &= ~PARENB;
-
options.c_cflag &= ~CSTOPB;
-
break;
-
default:
-
fprintf (stderr, "Unsupported parity\n");
-
return (FALSE);
-
}
-
-
switch (stopbits)
-
{
-
case 1:
-
options.c_cflag &= ~CSTOPB;
-
break;
-
case 2:
-
options.c_cflag |= CSTOPB;
-
break;
-
default:
-
fprintf (stderr, "Unsupported stop bits\n");
-
return (FALSE);
-
}
-
-
if (parity != 'n')
-
options.c_iflag |= INPCK;
-
tcflush (fd, TCIFLUSH);
-
options.c_cc[VTIME] = 150;
-
options.c_cc[VMIN] = 0;
-
if (tcsetattr (fd, TCSANOW, &options) != 0)
-
{
-
perror ("SetupSerial 3");
-
return (FALSE);
-
}
-
return (TRUE);
-
}
-
-
void
-
signal_handler_IO (int status)
-
{
-
printf ("received SIGIO signale.\n");
-
wait_flag = noflag;
-
}
-
-
int
-
main ()
-
{
-
printf ("This program updates last time at %s %s\n", __TIME__, __DATE__);
-
printf ("STDIO COM1\n");
-
int fd;
-
struct sigaction saio;
-
fd = open ("/dev/ttyUSB0", O_RDWR);
-
if (fd == -1)
-
{
-
perror ("serialport error\n");
-
}
-
else
-
{
-
printf ("open ");
-
printf ("%s", ttyname (fd));
-
printf (" succesfully\n");
-
}
-
-
saio.sa_handler = signal_handler_IO;
-
sigemptyset (&saio.sa_mask);
-
saio.sa_flags = 0;
-
saio.sa_restorer = NULL;
-
sigaction (SIGIO, &saio, NULL);
-
-
-
fcntl (fd, F_SETOWN, getpid ());
-
-
fcntl (fd, F_SETFL, FASYNC);
-
-
set_speed (fd, 115200);
-
if (set_Parity (fd, 8, 1, 'N') == FALSE)
-
{
-
printf ("Set Parity Error\n");
-
exit (0);
-
}
-
-
char buf[255];
-
while (STOP == 0)
-
{
-
usleep (100000);
-
-
if (wait_flag == 0)
-
{
-
memset (buf, 0, sizeof(buf));
-
res = read (fd, buf, 255);
-
printf ("nread=%d,%s\n", res, buf);
-
-
-
wait_flag = flag;
-
}
-
}
-
-
-
close (fd);
-
return 0;
-
}
代码三:通过select系统调用进行io多路切换,实现异步读取串口数据
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
int wait_flag = noflag;
-
int STOP = 0;
-
int res;
-
-
int speed_arr[] =
-
{ B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,
-
B4800, B2400, B1200, B300, };
-
int name_arr[] =
-
{ 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400,
-
1200, 300, };
-
void
-
set_speed (int fd, int speed)
-
{
-
int i;
-
int status;
-
struct termios Opt;
-
tcgetattr (fd, &Opt);
-
for (i = 0; i < sizeof (speed_arr) / sizeof (int); i++)
-
{
-
if (speed == name_arr[i])
-
{
-
tcflush (fd, TCIOFLUSH);
-
cfsetispeed (&Opt, speed_arr[i]);
-
cfsetospeed (&Opt, speed_arr[i]);
-
status = tcsetattr (fd, TCSANOW, &Opt);
-
if (status != 0)
-
{
-
perror ("tcsetattr fd1");
-
return;
-
}
-
tcflush (fd, TCIOFLUSH);
-
}
-
}
-
}
-
-
int
-
set_Parity (int fd, int databits, int stopbits, int parity)
-
{
-
struct termios options;
-
if (tcgetattr (fd, &options) != 0)
-
{
-
perror ("SetupSerial 1");
-
return (FALSE);
-
}
-
options.c_cflag &= ~CSIZE;
-
switch (databits)
-
{
-
case 7:
-
options.c_cflag |= CS7;
-
break;
-
case 8:
-
options.c_cflag |= CS8;
-
break;
-
default:
-
fprintf (stderr, "Unsupported data size\n");
-
return (FALSE);
-
}
-
switch (parity)
-
{
-
case 'n':
-
case 'N':
-
options.c_cflag &= ~PARENB; /* Clear parity enable */
-
options.c_iflag &= ~INPCK; /* Enable parity checking */
-
break;
-
case 'o':
-
case 'O':
-
options.c_cflag |= (PARODD | PARENB);
-
options.c_iflag |= INPCK; /* Disnable parity checking */
-
break;
-
case 'e':
-
case 'E':
-
options.c_cflag |= PARENB; /* Enable parity */
-
options.c_cflag &= ~PARODD;
-
options.c_iflag |= INPCK; /* Disnable parity checking */
-
break;
-
case 'S':
-
case 's': /*as no parity */
-
options.c_cflag &= ~PARENB;
-
options.c_cflag &= ~CSTOPB;
-
break;
-
default:
-
fprintf (stderr, "Unsupported parity\n");
-
return (FALSE);
-
}
-
-
switch (stopbits)
-
{
-
case 1:
-
options.c_cflag &= ~CSTOPB;
-
break;
-
case 2:
-
options.c_cflag |= CSTOPB;
-
break;
-
default:
-
fprintf (stderr, "Unsupported stop bits\n");
-
return (FALSE);
-
}
-
/* Set input parity option */
-
if (parity != 'n')
-
options.c_iflag |= INPCK;
-
tcflush (fd, TCIFLUSH);
-
options.c_cc[VTIME] = 150;
-
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
-
if (tcsetattr (fd, TCSANOW, &options) != 0)
-
{
-
perror ("SetupSerial 3");
-
return (FALSE);
-
}
-
return (TRUE);
-
}
-
-
void
-
signal_handler_IO (int status)
-
{
-
printf ("received SIGIO signale.\n");
-
wait_flag = noflag;
-
}
-
-
int
-
main ()
-
{
-
printf ("This program updates last time at %s %s\n", __TIME__, __DATE__);
-
printf ("STDIO COM1\n");
-
int fd;
-
fd = open ("/dev/ttyUSB0", O_RDWR);
-
if (fd == -1)
-
{
-
perror ("serialport error\n");
-
}
-
else
-
{
-
printf ("open ");
-
printf ("%s", ttyname (fd));
-
printf (" succesfully\n");
-
}
-
-
set_speed (fd, 115200);
-
if (set_Parity (fd, 8, 1, 'N') == FALSE)
-
{
-
printf ("Set Parity Error\n");
-
exit (0);
-
}
-
-
char buf[255];
-
fd_set rd;
-
int nread = 0;
-
while(1)
-
{
-
FD_ZERO(&rd);
-
FD_SET(fd, &rd);
-
while(FD_ISSET(fd, &rd))
-
{
-
if(select(fd+1, &rd, NULL,NULL,NULL) < 0)
-
{
-
perror("select error\n");
-
}
-
else
-
{
-
while((nread = read(fd, buf, sizeof(buf))) > 0)
-
{
-
printf("nread = %d,%s\n",nread, buf);
-
printf("test\n");
-
memset(buf, 0 , sizeof(buf));
-
}
-
}
-
}
-
}
-
close (fd);
-
return 0;
-
}
-
转载:http://blog.csdn.net/bg2bkk/article/details/8668576
阅读(1455) | 评论(0) | 转发(0) |