测试程序之UART 232/485适用于Android/Linux

简介: 测试程序之UART 232/485适用于Android/Linux

当时写这个的初衷是因为在调试Linux系统 , 串口测试费劲 通过echo/cat 有些功能受限制。

所以就搞了个测试程序 , Android可以不用这个 , 大把的测试工具。

程序功能介绍

这个程序是用来实现串口通信的。它接受三个参数,分别是通信模式(232或485)、串口设备名和波特率。它会根据参数的设置,打开指定的串口,并设置相应的属性。然后,它会创建一个子进程,用于从串口读取数据,并在标准输出上显示。父进程则用于从标准输入读取用户输入的内容,并发送到串口。用户可以输入文本或十六进制字符串,程序会自动识别并转换成字节序列。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
 
#define MODE_232 1
#define MODE_485 2
 
int open_serial_port(const char *port, int baud_rate, int mode)
{
    struct termios tty;
    memset(&tty, 0, sizeof(tty));
 
    int fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd < 0) {
        perror("open");
        return -1;
    }
 
    if (tcgetattr(fd, &tty) != 0) {
        perror("tcgetattr");
        close(fd);
        return -1;
    }
 
    cfsetospeed(&tty, baud_rate);
    cfsetispeed(&tty, baud_rate);
 
    // 设置控制模式(本地连接,接受使能)
    tty.c_cflag |= (CLOCAL | CREAD);
 
    // 设置数据位
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;
 
    // 设置奇偶校验位
    tty.c_cflag &= ~PARENB;
    tty.c_iflag &= ~INPCK;
 
    // 设置停止位数
    tty.c_cflag &= ~CSTOPB;
 
    // 设置等待时间和最小字符数(对应VTIME和VMIN两个参数),这里设为 10 秒和 0 个字符
    tty.c_cc[VTIME] = 100;
    tty.c_cc[VMIN] = 0;
 
    if (mode == MODE_485) {
        // 设置为RS485模式
        tty.c_cflag |= CRTSCTS | CLOCAL;
        tty.c_iflag &= ~(IXON | IXOFF | IXANY);
    } else if (mode == MODE_232) {
        // 设置为RS232模式
        tty.c_cflag &= ~CRTSCTS;
        tty.c_iflag |= (IXON | IXOFF | IXANY);
    }
 
    // 清空输入输出缓冲区
    tcflush(fd, TCIOFLUSH);
 
    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        perror("tcsetattr");
        close(fd);
        return -1;
    }
 
    return fd;
}
 
void read_serial_port(int fd)
{
    char buf[256];
    int n;
 
    while (1) {
        memset(buf, 0, sizeof(buf));
        n = read(fd, buf, sizeof(buf));
        if (n > 0) {
            printf("读到: %s", buf);
        }
    }
}
void write_serial_port(int fd)
{
    char buf[256];
    int n;
 
    while (1) {
        printf("请输入发送内容:");
        fgets(buf, sizeof(buf), stdin);
        n = strlen(buf);
 
        if (n > 0) {
            // 去掉最后的换行符
            if (buf[n-1] == '\n') {
                buf[n-1] = '\0';
                n--;
            }
 
            // 判断输入的字符串是否是十六进制格式
            int is_hex = 1;
            int i;
            for (i = 0; i < n; i++) {
                if ((buf[i] >= '0' && buf[i] <= '9')
                    || (buf[i] >= 'a' && buf[i] <= 'f')
                    || (buf[i] >= 'A' && buf[i] <= 'F')) {
                    continue;
                } else if (buf[i] == ' ') {
                    continue;
                } else {
                    is_hex = 0;
                    break;
                }
            }
 
            if (is_hex) {
                // 将输入的十六进制字符串转换成字节序列
                unsigned char data[128];
                int j = 0;
                for (i = 0; i < n; i++) {
                    if (buf[i] == ' ') {
                        continue;
                    }
 
                    sscanf(&buf[i], "%02X", &data[j]);
                    j++;
                    i++;
                }
                n = j;
                if (n > 0) {
                    n = write(fd, data, n);
                    if (n < 0) {
                        perror("write");
                    } else {
                        printf("hex发送成功\n");
                    }
                }
            } else {
                // 直接将输入的文本发送到串口
                n = write(fd, buf, n);
                if (n < 0) {
                    perror("write");
                } else {
                    printf("txt发送成功\n");
                }
            }
        }
    }
}
int main(int argc, char *argv[])
{
    if (argc != 4) {
        printf("Usage: %s [mode] [serial port] [baud rate]\n", argv[0]);
        return 1;
    }
 
    int mode;
    if (strcmp(argv[1], "232") == 0) {
        mode = MODE_232;
    } else if (strcmp(argv[1], "485") == 0) {
        mode = MODE_485;
    } else {
        printf("Invalid mode: %s\n", argv[1]);
        return 1;
    }
 
    const char *port = argv[2];
    int baud_rate = atoi(argv[3]);
 
    int fd = open_serial_port(port, baud_rate, mode);
    if (fd < 0) {
        fprintf(stderr, "Failed to open serial port %s with baud rate %d\n", port, baud_rate);
        return 1;
    }
 
    printf("Serial port %s opened successfully with baud rate %d and mode %d\n", port, baud_rate, mode);
 
    pid_t pid = fork();
    if (pid == 0) {
    // 子进程用于读取数据
    read_serial_port(fd);
} else if (pid > 0) {
    // 父进程用于写数据
    write_serial_port(fd);
} else {
    perror("fork");
    return 1;
}
 
close(fd);
 
return 0;
}

使用示例

要编译这个程序,需要在终端中输入:

./gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc  -o serial serial.c

要运行这个程序,需要在终端中输入:

./serial [mode] [serial port] [baud rate]

例如:

./serial 232 /dev/ttyUSB0 115200 # 使用RS232模式打开/dev/ttyUSB0串口,并设置波特率为115200
./serial 485 /dev/ttyS0 9600 # 使用RS485模式打开/dev/ttyS0串口,并设置波特率为9600

然后就可以看到类似下面的输出:

Serial port /dev/ttyUSB0 opened successfully with baud rate 115200 and mode 232
请输入发送内容:Hello world!
txt发送成功
读到: Hello world!
请输入发送内容:01 02 03 04 05
hex发送成功
读到: 01 02 03 04 05



相关文章
|
27天前
|
设计模式 算法 前端开发
Android面经分享,失业两个月,五一节前拿到Offer,设计思想与代码质量优化+程序性能优化+开发效率优化
Android面经分享,失业两个月,五一节前拿到Offer,设计思想与代码质量优化+程序性能优化+开发效率优化
|
29天前
|
Linux Android开发
测试程序之提供ioctl函数应用操作GPIO适用于Linux/Android
测试程序之提供ioctl函数应用操作GPIO适用于Linux/Android
22 0
|
10天前
|
安全 Java Android开发
05. 【Android教程】Android 程序签名打包
05. 【Android教程】Android 程序签名打包
12 1
|
29天前
|
iOS开发 MacOS Windows
|
2天前
|
算法 Linux 测试技术
Linux编程:测试-高效内存复制与随机数生成的性能
该文探讨了软件工程中的性能优化,重点关注内存复制和随机数生成。文章通过测试指出,`g_memmove`在内存复制中表现出显著优势,比简单for循环快约32倍。在随机数生成方面,`GRand`库在1000万次循环中的效率超过传统`rand()`。文中提供了测试代码和Makefile,建议在性能关键场景中使用`memcpy`、`g_memmove`以及高效的随机数生成库。
|
14天前
|
安全 物联网 测试技术
构建未来:Android与IoT设备的无缝交互深入探索软件自动化测试的未来趋势
【5月更文挑战第30天】在物联网(IoT)技术快速发展的当下,Android系统因其开放性和广泛的用户基础成为了连接智能设备的首选平台。本文将探讨如何通过现代Android开发技术实现智能手机与IoT设备的高效、稳定连接,并分析其中的挑战和解决方案。我们将深入挖掘Android系统的底层通信机制,提出创新的交互模式,并通过实例演示如何在Android应用中集成IoT控制功能,旨在为开发者提供一套可行的指导方案,促进IoT生态系统的进一步发展。
|
15天前
|
分布式计算 Java 测试技术
Spark 单元测试报Error:(26, 16) java: 程序包sun.misc不存在
Spark 单元测试报Error:(26, 16) java: 程序包sun.misc不存在
20 0
|
20天前
|
Android开发 数据安全/隐私保护 iOS开发
ios和安卓测试包发布网站http://fir.im的注册与常用功能
ios和安卓测试包发布网站http://fir.im的注册与常用功能
17 0
ios和安卓测试包发布网站http://fir.im的注册与常用功能
|
29天前
|
测试技术
LabVIEW程序测试
LabVIEW程序测试
15 1
|
29天前
|
XML Java Android开发
如何美化android程序:自定义ListView背景
如何美化android程序:自定义ListView背景
11 2