0

我必须在 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();
    }
}
4

1 回答 1

0

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

这意味着当您 write() (和读取,就此而言)时,如果端口已经忙,它不会阻塞等待写入完成。

相反,它将返回 -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是O_NONBLOCK的别名),只是重新设置了flag。

    fcntl(fd, F_SETFL, O_SYNC); 

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

于 2013-07-16T10:53:43.430 回答