为什么我在串口上连续接收数据?

时间:2017-02-16 15:41:49

标签: c linux serial-port

我买了一个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...

1 个答案:

答案 0 :(得分:0)

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

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