c-串口配置帮助.read()和write()返回-1和串行通信停止.why



我必须用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/ttyS0n");
            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%lxn", (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("%Xn", 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();
    }
}

您已将文件描述符配置为非阻塞模式。

这意味着当您写()(和读)时,如果端口已经很忙,它不会阻止等待写完成。

相反,它将返回-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_NDELLAY的兼容别名,它是O_NONBLOCK的别名),它只是再次设置了标志。

    fcntl(fd, F_SETFL, O_SYNC); 

这是你不想要的。但我不认为这会对事情造成重大伤害。这将导致写入操作不使用任何缓冲。

最新更新