我正在尝试从其他设备发送的串口读取数据。 在我的串口接收部分,我使用信号处理程序读取读取缓冲区中的数据。 它可以工作,但是对于相同的数据有一些触发器,有时它会停止工作。 我的接收计划是
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <iostream>
#include <strings.h>
#include <stdlib.h>
#include <sys/signal.h>
#include <sys/ioctl.h>
using namespace std;
/* baudrate settings are defined in <asm/termbits.h>, which is
included by <termios.h> */
#define BAUDRATE B9600
/* change this definition for the correct port */
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1
int fd;
int res;
char buf[255];
volatile int STOP=FALSE;
void signal_handler_IO (int status); /* definition of signal handler */
main()
{
struct termios oldtio,newtio;
struct sigaction saio;
/*
Open modem device for reading and writing and not as controlling tty
because we don't want to get killed if linenoise sends CTRL-C.
*/
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
if (fd <0) {perror(MODEMDEVICE); exit(-1); }
tcgetattr(fd,&oldtio); /* save current serial port settings */
bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
/*
BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
CRTSCTS : output hardware flow control (only used if the cable has
all necessary lines. See sect. 7 of Serial-HOWTO)
CS8 : 8n1 (8bit,no parity,1 stopbit)
CLOCAL : local connection, no modem contol
CREAD : enable receiving characters
*/
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
/*
IGNPAR : ignore bytes with parity errors
ICRNL : map CR to NL (otherwise a CR input on the other computer
will not terminate input)
otherwise make device raw (no other input processing)
*/
newtio.c_iflag = IGNPAR | ICRNL;
/*
Raw output.
*/
newtio.c_oflag = 0;
/*
ICANON : enable canonical input
disable all echo functionality, and don't send signals to calling program
*/
newtio.c_lflag = ICANON;
/*set signal*/
saio.sa_handler = signal_handler_IO;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
fcntl(fd, F_SETFL, FNDELAY|FASYNC);
fcntl(fd, F_SETOWN, getpid());
/*
initialize all control characters
default values can be found in /usr/include/termios.h, and are given
in the comments, but we don't need them here
*/
newtio.c_cc[VINTR] = 0; /* Ctrl-c */
newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */
newtio.c_cc[VERASE] = 0; /* del */
newtio.c_cc[VKILL] = 0; /* @ */
newtio.c_cc[VEOF] = 4; /* Ctrl-d */
newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
newtio.c_cc[VSWTC] = 0; /* '\0' */
newtio.c_cc[VSTART] = 0; /* Ctrl-q */
newtio.c_cc[VSTOP] = 0; /* Ctrl-s */
newtio.c_cc[VSUSP] = 0; /* Ctrl-z */
newtio.c_cc[VEOL] = 0; /* '\0' */
newtio.c_cc[VREPRINT] = 0; /* Ctrl-r */
newtio.c_cc[VDISCARD] = 0; /* Ctrl-u */
newtio.c_cc[VWERASE] = 0; /* Ctrl-w */
newtio.c_cc[VLNEXT] = 0; /* Ctrl-v */
newtio.c_cc[VEOL2] = 0; /* '\0' */
/*
now clean the modem line and activate the settings for the port
*/
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
ioctl(fd, TCIFLUSH, 0);
ioctl(fd, TCIFLUSH, 1);
/*
terminal settings done, now handle input
In this example, inputting a 'z' at the beginning of a line will
exit the program.
*/
while (STOP==FALSE) {
}
/* restore the old port settings */
tcsetattr(fd,TCSANOW,&oldtio);
}
void signal_handler_IO (int status)
{
res = read(fd,buf,255);
buf[res]=0; /* set end of string, so we can printf */
printf("%s\n", buf);
ioctl(fd, TCIFLUSH, 0);
}
对于此测试,我在Raspberry PI中进行了测试,并使用USB-SERIAL适配器从USB端口发送数据。我用Python发送数据的模拟程序是
#!/usr/bin/env python
import time
import serial
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate = 9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
counter=0
while 1:
ser.write('Write counter: %d \n'%(counter))
time.sleep(1)
counter += 1
有效。但它会触发一些数据
root@raspberrypi:/home/pi/Softwares/SerialPortTest/build# ./SerialPortTest
Write counter: 3
Write counter: 4
Write counter: 5
Write counter: 5
Write counter: 5
Write counter: 5
Write counter: 5
Write counter: 5
Write counter: 5
Write counter: 5
Write counter: 8
Write counter: 9
Write counter: 10
Write counter: 11
Write counter: 11
Write counter: 11
Write counter: 11
^C
root@raspberrypi:/home/pi/Softwares/SerialPortTest/build# ./SerialPortTest
Write counter: 23
Write counter: 24
Write counter: 24
Write counter: 24
Write counter: 24
Write counter: 24
在描述发生的事情时,它为Write counter: 5
触发了几次,然后程序停在Write counter: 11
。我停止了程序并再次运行。然后有时,我失去了Write counter: 6 and Write counter: 7
。我该如何解决这个问题呢?