我必须在C中创建一个程序,以便我可以通过串口与设备通信。端口配置应为9600BPS起始位:1个数据位:8奇偶校验位:偶数停止位:1。我发送给你一份我如何配置端口的副本,但是我遇到了问题,我可以解决它。
我每100到200毫秒向设备发送一个状态请求,设备应该回复,因为我有一个计时器。在上电序列中,我向设备发送命令,设备正在响应,但是在发送和接收一些命令之后,发送停止,因此接收也停止,我注意到写命令和读命令发回-1,之后什么也没发生。为什么会这样?
是因为我正在尝试阅读,而且我没有什么可读的,所以在这种情况下我得到-1,但如果是这样的话,为什么我写完之后有-1? 感谢所有帮助。
int main(int argc, char *argv[]) {
timer_t tid = 0;
struct itimerspec it;
fd = open("/dev/ttyUSB1", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror("open_port: Unable to open /dev/ttyS0\n");
exit(1);
}
satimer.sa_handler = signal_handler_TIMER;
satimer.sa_flags = 0;
satimer.sa_restorer = NULL;
sigaction(SIGALRM, &satimer, NULL);
it.it_value.tv_sec = 0;
it.it_value.tv_nsec = 10000000;
it.it_interval.tv_sec = 0;
it.it_interval.tv_nsec = 10000000;
if (timer_create(CLOCK_REALTIME, NULL, &tid) == -1)
fprintf(stderr, "error in timer_create \n");
// printf("timer ID is 0x%lx\n", (long) tid);
if (timer_settime(tid, 0, &it, NULL) == -1)
fprintf(stderr, "error in settime \n");
fcntl(fd, F_SETFL, FNDELAY);
fcntl(fd, F_SETOWN, getpid());
fcntl(fd, F_SETFL, O_SYNC);
tcgetattr(fd, &termAttr);
//baudRate = B115200; /* Not needed */
cfsetispeed(&termAttr, B9600);
cfsetospeed(&termAttr, B9600);
termAttr.c_cflag |= PARENB;
termAttr.c_cflag &= ~PARODD;
termAttr.c_cflag &= ~CSTOPB;
termAttr.c_cflag &= ~CSIZE;
termAttr.c_cflag |= CS8;
termAttr.c_cflag |= (CLOCAL | CREAD);
termAttr.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
termAttr.c_iflag &= ~(IXON | IXOFF | IXANY);
termAttr.c_oflag &= ~OPOST;
termAttr.c_cc[VMIN] = 5;
termAttr.c_cc[VTIME] = 5;
tcsetattr(fd, TCSANOW, &termAttr);
CleanRxBuffer();
PowerUp();
......
void PowerUp(void){
unsigned char *p_commands,ima,komanda = STATUS_REQUEST;
p_commands = &comandi[0];
unsigned char *p_tx_buffer_;
for (;;) {
if ((milisekundi == 10) || (milisekundi == 30) || (milisekundi == 50)
|| (milisekundi == 70) || (milisekundi == 90)) {
makeTXpaket(0x00);
makeTXpaket(komanda);
p_tx_buffer_ = &tx_buffer[1];
nbytes = write(fd, tx_buffer, *p_tx_buffer_);
if (nbytes != sizeof(tx_buffer)) {
/* problem! */
printf("error writing on serial port!!!");
}
sleep(0.2);
bytes = read(fd, rx_buffer, sizeof(rx_buffer));
if (bytes != sizeof(rx_buffer)) {
/* problem! */
printf("error reading on serial port!!!\n");
}
printf("%X\n", rx_buffer);
}
ima = CheckRXbuffer();
if ((answer == 0x40) && (ima != 0x00)) {
p_commands++;
komanda = *p_commands;
}
if ((answer == 0x50) && (ima != 0x00)){
p_commands++;
komanda = *p_commands;
}
if ((answer == 0x1B) && (ima != 0x00)){
p_commands++;
komanda = *p_commands;
}
if ((answer == 0xC0) && (ima != 0x00)){
p_commands++;
komanda = *p_commands;
}
if ((answer == 0xC4) && (ima != 0x00)){
p_commands++;
komanda = *p_commands;
}
if ((answer == 0xC1) && (ima != 0x00)){
p_commands++;
komanda = *p_commands;
}
if ((answer == 0xC2) && (ima != 0x00)){
p_commands++;
komanda = *p_commands;
}
if ((answer == 0xC5) && (ima != 0x00)){
p_commands++;
komanda = *p_commands;
}
if ((answer == 0xC6) && (ima != 0x00)){
p_commands++;
komanda = *p_commands;
}
if ((answer == 0xC7) && (ima != 0x00)){
p_commands++;
komanda = *p_commands;
}
if ((answer == 0xC3) && (ima != 0x00)){
p_commands++;
komanda = *p_commands;
}
if ((answer == 0x11) && (ima != 0x00)){
break;
}
if ((*p_commands) == 0xFF) {
break;
}
CleanRxBuffer();
}
}
答案 0 :(得分:0)
您已将文件描述符配置为非阻塞模式。
这意味着当你写()(并读取)时,如果端口已经忙,它将不会阻止等待写完成。
相反,它将返回-1并将errno设置为EAGAIN(或EWOULDBLOCK)。
所以,解决这个问题:
fd = open("/dev/ttyUSB1", O_RDWR | O_NOCTTY | O_NDELAY);
删除O_NDELAY。 O_NDELAY是O_NONBLOCK的别名,这就是使read()和write()的行为与你看到的一样。
fcntl(fd, F_SETFL, FNDELAY);
这与O_NDELAY相同(事实上,FNDELAY是O_NDELAY的兼容性别名,它是O_NONBLOCK的别名),它只是再次设置标志。
fcntl(fd, F_SETFL, O_SYNC);
这是你不想要的。但我认为这不会对事情造成太大伤害。它会导致写入不使用任何缓冲。