【问题标题】:Why do I receive data continuously on my serial port?为什么我的串口连续接收数据?
【发布时间】:2017-02-16 15:41:49
【问题描述】:

我买了一个 GSM 模块,我试图通过 USB 转串口(FT232 命名组件)来控制它。

我在 GSM 模块之前编写了一个小程序来测试 FT232(通过将 TX 连接到 RX),我遇到了一个问题。

我可以发送数据(通常是“AT\r”)并且可以接收相同的数据(希望如此),但我会一次又一次地接收数据(通常是“0x0A”,有时是原始数据:“AT\r”)。 ..

你能帮我解决这个问题吗?


main.c 的代码

#include    <fcntl.h>
#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <sys/ioctl.h>
#include    <sys/select.h>
#include    <sys/time.h>
#include    <sys/types.h>
#include    <termios.h>
#include    <unistd.h>

int open_serial();

int close_serial(int serial_fd);

int read_serial (int fd);

int main ()
{
    int serial_fd = open_serial();

    if (serial_fd == EXIT_FAILURE)
        return EXIT_FAILURE;

    struct termios old_termios;
    struct termios serial_termios;

    //  Port configuration backup
    tcgetattr(serial_fd, &old_termios);
    serial_termios = old_termios;
    //  Port setup
    serial_termios.c_cflag |= (B9600 | CS8 | CLOCAL | CREAD);
    serial_termios.c_lflag |= (ICANON);
    //  Port configuration update
    tcsetattr(serial_fd, TCSANOW, &serial_termios);

    int num_char;
    char* str2send = "AT\r";

    num_char = write(serial_fd, str2send, strlen(str2send));
    if (num_char < 0)
    {
        fputs("FAIL !\n", stderr);
    }
    else
    {
        printf("%d char sended\n", num_char);
    }

    fd_set  serial_in;
    int count=0;    

    while ((read_serial(serial_fd) > 0) & (count < 25))
        count++;

    //  Port configuration restore
    tcsetattr(serial_fd, TCSANOW, &old_termios);

    return close_serial(serial_fd);
}

int open_serial()
{
    int serial_fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);

    printf("Serial port opening...\n");
    if (serial_fd == -1)
    {
        printf("FAIL !\n");
        perror("open()");
        return EXIT_FAILURE;
    }
    printf("SUCCESS ! [FD] : [%02d]\n", serial_fd);

    return serial_fd;
}

int close_serial(int serial_fd)
{
    printf("Serial port closing...\n[FD] : [%02d]\n", serial_fd);
    if (close(serial_fd) == -1)
    {
        printf("FAIL !\n");
        perror("close()");
        return EXIT_FAILURE;
    }
    printf("SUCCESS !\n");

    return EXIT_SUCCESS;
}
int read_serial (int fd)
{
    char rcv_serial [256];
    int max_fd = fd + 1;
    fd_set input;
    FD_ZERO(&input);
    FD_SET(fd, &input);
    int count;
    //  1sec timeout
    struct timeval timeout;
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    int nb_char, ret_read;
    int ret_sel = select(max_fd, &input, NULL, NULL, &timeout);
    if (ret_sel < 0)
    {
        perror("select() :");
    }
    else if (ret_sel == 0)
    {
        printf("TIMEOUT\n");
    }
    else
    {
        if (FD_ISSET(fd, &input))
        {
            nb_char = 10;
            ioctl(fd, FIONREAD, &nb_char);
            printf("%d chars availables\n", nb_char);
            ret_read = read(fd, &rcv_serial, nb_char);
            printf("[ RET READ : %d]\n", ret_read);
            rcv_serial[ret_read] ='\0';
            for (count = 0; count < ret_read; count++)
                printf("[%02X]", rcv_serial[count]);
            printf("\n");
            //printf("[%s]\n", rcv_serial);
        }
    }
    return ret_sel;
}

结果

Serial port opening...
SUCCESS ! [FD] : [03]
3 char sended
3 chars availables
[ RET READ : 3]
[41][54][0A]
3 chars availables
[ RET READ : 3]
[41][54][0A]
1 chars availables
[ RET READ : 1]
[0A]
3 chars availables
[ RET READ : 3]
[41][54][0A]
1 chars availables
[ RET READ : 1]
[0A]
1 chars availables
[ RET READ : 1]
[0A]
1 chars availables
[ RET READ : 1]
[0A]
3 chars availables
[ RET READ : 3]
[41][54][0A]
1 chars availables
[ RET READ : 1]
[0A]
1 chars availables
[ RET READ : 1]
[0A]
1 chars availables
[ RET READ : 1]
[0A]
Serial port closing...

【问题讨论】:

  • 如果在没有新数据的情况下继续读DR,还是一样的。 AT 命令以"\r\n" 结尾,'\n 可能以' == 0xA 结尾,所以说得通。
  • 感谢您的回答。这个命令很有意义,但是我怎么知道是有新消息还是来电?我应该不断检查串口吗?
  • @Fiddling-Bits,您说芯片的寄存器在没有收到新数据时不会改变,因此包含收到的最后一个字符。很有意义。知道他拨打read_serial 有什么问题吗?在没有收到新数据时它应该阻塞还是返回零?
  • read_serial 返回选择的值。就我而言,它总是返回一个 > 0 的值,就好像有新数据一样
  • 我添加了输出,我们可以看到,输出有时会发生变化。我不明白为什么

标签: c linux serial-port


【解决方案1】:

感谢@sawdust 评论。 我添加这个来解决我禁用输入回声的问题:

serial_termios.c_lflag &= ~(ECHO | ECHOE | ECHONL | IEXTEN)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 2020-05-18
    • 1970-01-01
    • 2015-02-05
    • 2021-04-04
    • 1970-01-01
    相关资源
    最近更新 更多