【Linux C】串口测试代码

 编译生成a.out 后执行

./a.out /dev/ttyS3 38400 8 0 1 0

代表  打开/dev/ttyS3 以波特率:38400 数据位8 校验位无 停止位1  接受数据的方式(1代表发送) 打开

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termio.h>
#include <time.h>


#define MAX_BUF_SIZE     2048
char buf[MAX_BUF_SIZE+2];

#define MY_END_CHAR      0x13


int setup_port(int fd, int baud, int databits, int parity, int stopbits);
int reset_port(int fd);
int read_data(int fd, void *buf, int len);
int write_data(int fd, void *buf, int len);
void print_usage(char *program_name);


int main(int argc, char *argv[]) //./a.out /dev/ttyS3 38400 8 0 1 0
{
    int fd;
    int baud;
    int len;
    int count;
    int i;
    int databits;
    int stopbits;
    int parity;
    int read_or_write;


    if (argc != 7) {
        print_usage(argv[0]);
        return 1;
    }

    baud = atoi(argv[2]);
    if ((baud < 0) || (baud > 921600)) {
        fprintf(stderr, "Invalid baudrate!\n");
        return 1;
    }

    databits = atoi(argv[3]);
    if ((databits < 5) || (databits > 8)) {
        fprintf(stderr, "Invalid databits!\n");
        return 1;
    }

    parity = atoi(argv[4]);
    if ((parity < 0) || (parity > 2)) {
        fprintf(stderr, "Invalid parity!\n");
        return 1;
    }

    stopbits = atoi(argv[5]);
    if ((stopbits < 1) || (stopbits > 2)) {
        fprintf(stderr, "Invalid stopbits!\n");
        return 1;
    }

    read_or_write = atoi(argv[6]);

    fd = open(argv[1], O_RDWR, 0);
    if (fd < 0) {
        fprintf(stderr, "open <%s> error %s\n", argv[1], strerror(errno));
        return 1;
    }

    if (setup_port(fd, baud, databits, parity, stopbits)) {
        fprintf(stderr, "setup_port error %s\n", strerror(errno));
        close(fd);
        return 1;
    }

    count = 0;

    if (read_or_write) {
        fprintf(stderr, "Begin to send:\n");

        while ( (len = read(0, buf, MAX_BUF_SIZE)) > 0 ) {
            if (len == 1) {
                buf[0] = MY_END_CHAR;
                buf[1] = 0;
                write_data(fd, buf, len);
                break;
            }

            
            i = write_data(fd, buf, len);
            if (i == 0) {
                fprintf(stderr, "Send data error!\n");
                break;
            }

            //count += len;
            //fprintf(stderr, "Send %d bytes\n", len);
        }

    } else {

        fprintf(stderr, "Begin to recv:\n");
	int x = 0;
        len = MAX_BUF_SIZE;

        while (1) {
            
            i = read_data(fd, buf, len);
            if (i > 0) {
                //count += i;
                //fprintf(stderr, "Recv %d byte\n", i);
		for(x=0;x<i;x++)
                fprintf(stderr,"%02X", buf[x]);
                if (buf[i-1] == MY_END_CHAR) {
                    break;
                }
            }
        }
    }

    reset_port(fd);
    close(fd);

    return 0;
}


static int baudflag_arr[] = {
    B921600, B460800, B230400, B115200, B57600, B38400,
    B19200,  B9600,   B4800,   B2400,   B1800,  B1200,
    B600,    B300,    B150,    B110,    B75,    B50
};
static int speed_arr[] = {
    921600,  460800,  230400,  115200,  57600,  38400,
    19200,   9600,    4800,    2400,    1800,   1200,
    600,     300,     150,     110,     75,     50
};


int speed_to_flag(int speed)
{
    int i;

    for (i = 0;  i < sizeof(speed_arr)/sizeof(int);  i++) {
        if (speed == speed_arr[i]) {
            return baudflag_arr[i];
        }
    }

    fprintf(stderr, "Unsupported baudrate, use 9600 instead!\n");
    return B9600;
}


static struct termio oterm_attr;

int setup_port(int fd, int baud, int databits, int parity, int stopbits)
{
    struct termio term_attr;

    
    if (ioctl(fd, TCGETA, &term_attr) < 0) {
        return -1;
    }

    
    memcpy(&oterm_attr, &term_attr, sizeof(struct termio));

    term_attr.c_iflag &= ~(INLCR | IGNCR | ICRNL | ISTRIP);
    term_attr.c_oflag &= ~(OPOST | ONLCR | OCRNL);
    term_attr.c_lflag &= ~(ISIG | ECHO | ICANON | NOFLSH);
    term_attr.c_cflag &= ~CBAUD;
    term_attr.c_cflag |= CREAD | speed_to_flag(baud);

    
    term_attr.c_cflag &= ~(CSIZE);
    switch (databits) {
        case 5:
            term_attr.c_cflag |= CS5;
            break;

        case 6:
            term_attr.c_cflag |= CS6;
            break;

        case 7:
            term_attr.c_cflag |= CS7;
            break;

        case 8:
        default:
            term_attr.c_cflag |= CS8;
            break;
    }

    
    switch (parity) {
        case 1:  
            term_attr.c_cflag |= (PARENB | PARODD);
            break;

        case 2:  
            term_attr.c_cflag |= PARENB;
            term_attr.c_cflag &= ~(PARODD);
            break;

        case 0:  
        default:
            term_attr.c_cflag &= ~(PARENB);
            break;
    }


    
    switch (stopbits) {
        case 2:  
            term_attr.c_cflag |= CSTOPB;
            break;

        case 1:  
        default:
            term_attr.c_cflag &= ~CSTOPB;
            break;
    }

    term_attr.c_cc[VMIN] = 1;
    term_attr.c_cc[VTIME] = 0;

    if (ioctl(fd, TCSETAW, &term_attr) < 0) {
        return -1;
    }

    if (ioctl(fd, TCFLSH, 2) < 0) {
        return -1;
    }

    return 0;
}


int read_data(int fd, void *buf, int len)
{
    int count;
    int ret;

    ret = 0;
    count = 0;

    //while (len > 0) {

    ret = read(fd, (char*)buf + count, len);
    if (ret < 1) {
        fprintf(stderr, "Read error %s\n", strerror(errno));
        //break;
    }

    count += ret;
    len = len - ret;

    //}

    *((char*)buf + count) = 0;
    return count;
}


int write_data(int fd, void *buf, int len)
{
    int count;
    int ret;

    ret = 0;
    count = 0;

    while (len > 0) {

        ret = write(fd, (char*)buf + count, len);
        if (ret < 1) {
            fprintf(stderr, "Write error %s\n", strerror(errno));
            break;
        }

        count += ret;
        len = len - ret;
    }

    return count;
}


void print_usage(char *program_name)
{
    fprintf(stderr,
            "*************************************\n"
            "  A Simple Serial Port Test Utility\n"
            "*************************************\n\n"
            "Usage:\n  %s <device> <baud> <databits> <parity> <stopbits> <read_or_write>\n"
            "       databits: 5, 6, 7, 8\n"
            "       parity: 0(None), 1(Odd), 2(Even)\n"
            "       stopbits: 1, 2\n"
            "       read_or_write: 0(read), 1(write)\n"
            "Example:\n  %s /dev/ttyS0 9600 8 0 1 0\n\n",
            program_name, program_name
           );
}


int reset_port(int fd)
{
    if (ioctl(fd, TCSETAW, &oterm_attr) < 0) {
        return -1;
    }

    return 0;
}

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: linux串口回环测试程序是一种测试串口通信功能的程序,通过将发送的数据回传给接收端进行验证,以确定串口是否正常工作。 要实现该测试程序,首先需要打开串口设备文件。在Linux中,串口设备文件通常位于/dev目录下,如/dev/ttyS0代表第一个串口设备。可以使用open()函数来打开串口设备文件,例如open("/dev/ttyS0", O_RDWR)。 接下来,需要设置串口的参数,包括波特率、数据位、停止位等。可以使用termios结构体和tcsetattr函数来设置串口参数,例如: struct termios oldTio, newTio; tcgetattr(fd, &oldTio); newTio = oldTio; cfsetispeed(&newTio, B9600); // 设置波特率为9600 cfsetospeed(&newTio, B9600); newTio.c_cflag &= ~PARENB; // 不启用奇偶校验 newTio.c_cflag &= ~CSTOPB; // 停止位为1 newTio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 关闭标准模式和回显 tcsetattr(fd, TCSANOW, &newTio); 然后,可以使用read()函数从串口读取接收到的数据,并使用write()函数将该数据发送回串口。可以使用一个循环来实现不断进行回环测试,例如: while (1) { char buffer[256]; int bytesRead = read(fd, buffer, sizeof(buffer)); write(fd, buffer, bytesRead); } 最后,需要关闭串口设备文件,可以使用close()函数来关闭已打开的串口设备文件,例如close(fd)。 通过运行该回环测试程序,可以验证串口设备是否正常工作,是否能正常发送和接收数据。 ### 回答2: Linux串口回环测试程序是一种用于测试串口通信功能的程序。串口是一种用于将数据通过物理电缆传输的通信接口,常用于连接计算机与外部设备。 Linux系统提供了一种简单而有效的方法来测试串口的功能,即通过发送数据并接收相同数据来完成回环测试。以下是一个实现简单串口回环测试的示例程序: 1. 首先,打开终端并进入Linux系统。 2. 使用命令行工具编写一个C语言程序,实现串口回环测试。 ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> int main() { int serial_port; char data[10] = "Hello!"; // 打开串口设备文件 serial_port = open("/dev/ttyS0", O_RDWR); if (serial_port < 0) { printf("无法打开串口设备文件。\n"); return -1; } // 配置串口 struct termios tty; tcgetattr(serial_port, &tty); cfsetospeed(&tty, B9600); cfsetispeed(&tty, B9600); tty.c_cflag &= ~PARENB; tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; tty.c_cflag &= ~CRTSCTS; tty.c_cflag |= CREAD | CLOCAL; tty.c_iflag &= ~(IXON | IXOFF | IXANY); tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); tty.c_oflag &= ~OPOST; tcsetattr(serial_port, TCSANOW, &tty); // 发送数据 write(serial_port, &data, sizeof(data)); // 接收数据 char receivedData[10]; read(serial_port, &receivedData, sizeof(receivedData)); // 检查数据 if (strcmp(data, receivedData) == 0) { printf("串口回环测试成功!\n"); } else { printf("串口回环测试失败。\n"); } // 关闭串口 close(serial_port); return 0; } ``` 3. 保存程序并编译为可执行文件,例如命名为"serial_test"。 4. 运行程序,它将打开串口设备文件,并将数据发送到串口。然后,它将等待接收到来自串口的相同数据,并将其与发送的数据进行比较。如果两者相同,则表示串口回环测试成功,否则表示失败。 需要注意的是,在代码中使用的串口设备文件"/dev/ttyS0"是一个示例,实际使用时应根据不同的系统和串口配置来修改。 串口回环测试程序对于验证串口通信的可靠性和正确性非常有用。 ### 回答3: Linux串口回环测试程序可以通过打开两个串口设备,一个作为发送端口,一个作为接收端口,实现数据的发送和接收。具体步骤如下: 1. 首先,在终端中输入以下命令,加载UART设备驱动: ``` sudo modprobe serial ``` 2. 使用`ls /dev/tty*`命令查看系统中的串口设备,记下发送端口和接收端口的设备名称,例如`/dev/ttyUSB0`和`/dev/ttyUSB1`。 3. 创建一个C语言源文件,例如`serial_test.c`,编写串口回环测试程序的代码。 4. 在代码中,首先使用`open()`函数打开发送端口和接收端口的设备文件,成功打开后会返回一个文件描述符。 5. 接下来,使用`ioctl()`函数设置串口的通信参数,例如波特率、数据位、停止位和奇偶校验位等。这里可以使用`struct termios`结构体来设置通信参数。 6. 然后,利用`tcflush()`函数刷新发送端口和接收端口的输入输出缓冲区。 7. 接下来,进入一个循环,从发送端口读取数据,并将读取到的数据写入接收端口。可以使用`read()`函数和`write()`函数分别进行读取和写入操作。 8. 最后,使用`close()`函数关闭发送端口和接收端口的设备文件,释放资源。 9. 编译并运行程序,可以使用以下命令进行编译和执行: ``` gcc -o serial_test serial_test.c ./serial_test ``` 通过以上步骤,就可以实现Linux串口回环测试程序,用于测试串口的通信功能是否正常。在测试时,可以通过发送一些数据,并检查接收端是否能够正确接收到相同的数据,以验证串口的回环功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值