服务器测评网
我们一直在努力

Linux串口收发16进制数据,如何用命令行查看与解析?

在嵌入式开发、工业控制以及通信调试等领域,Linux 系统下的串口通信是一项基础且重要的技能,当需要传输或调试二进制数据时,16 进制格式的处理显得尤为关键,本文将详细介绍在 Linux 环境下进行串口 16 进制通信的相关知识,包括串口配置、16 进制数据的收发方法以及常见问题的解决方案。

Linux串口收发16进制数据,如何用命令行查看与解析?

Linux 串口通信基础

Linux 系统将串口设备抽象为字符设备文件,通常位于 /dev/ 目录下,如 /dev/ttyS0(COM1)、/dev/ttyUSB0(USB 转串口)等,在进行串口通信前,需要确保当前用户对设备文件具有读写权限,可通过 chmod 命令或加入 dialout 用户组解决。

串口通信的核心参数包括波特率、数据位、停止位、校验位和流控,这些参数需要收发双方保持一致,否则会导致数据解析错误,在 Linux 中,可通过 stty 命令快速配置串口参数,例如设置 /dev/ttyUSB0 的波特率为 115200、8 位数据位、1 位停止位、无校验位:

stty -F /dev/ttyUSB0 115200 cs8 -cstopb -parenb

还可使用 minicomscreen 等终端工具进行简单的串口调试,这些工具支持基本的字符收发,但在处理 16 进制数据时功能有限,因此需要更专业的工具或编程方法。

16 进制数据的表示与转换

16 进制(Hexadecimal)是计算机中常用的数据表示方法,基数为 16,使用 0-9 和 A-F(或 a-f)共 16 个字符,在串口通信中,16 进制数据常用于表示二进制文件、传感器数据或协议帧,字节 0x41 对应 ASCII 字符 ‘A’,而 0x00 表示空字节。

在 Linux 下进行 16 进制数据处理时,常使用 xxdhexdump 等命令行工具。xxd 可将二进制文件转换为 16 进制格式,也可反向转换:

# 将文件转换为 16 进制显示
xxd -g 1 file.bin
# 将 16 进制文件转换回二进制
xxd -r -p file.hex > file.bin

hexdump 则以更灵活的格式显示数据,支持自定义偏移量和显示格式:

Linux串口收发16进制数据,如何用命令行查看与解析?

hexdump -C file.bin  # 显示 ASCII 字符和偏移量

这些工具在调试串口数据时非常有用,可将接收到的原始字节流转换为可读的 16 进制格式,便于分析数据结构。

使用 C 语言进行串口 16 进制收发

在应用程序中处理串口 16 进制数据,通常需要结合系统调用和字符串解析,以下是使用 C 语言实现串口 16 进制发送与接收的基本步骤:

打开串口设备

使用 open() 函数打开串口设备文件,需设置 O_RDWR(读写模式)和 O_NOCTTY(不将终端作为控制终端)等标志:

int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0) {
    perror("Failed to open serial port");
    exit(1);
}

配置串口参数

通过 termios 结构体配置串口参数,包括波特率、数据位、停止位等:

struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag |= (CLOCAL | CREAD);
tcsetattr(fd, TCSANOW, &options);

16 进制字符串转换为二进制数据

发送 16 进制字符串(如 “A1 02 3F”)时,需先将其转换为二进制字节流,可通过逐字符解析实现:

void hex_to_bin(const char *hex, unsigned char *bin, int *len) {
    *len = 0;
    char *p = (char *)hex;
    while (*p) {
        if (isspace(*p)) {
            p++;
            continue;
        }
        unsigned char high = (*p >= 'A' && *p <= 'F') ? (*p - 'A' + 10) : (*p - '0');
        p++;
        if (!*p) break;
        unsigned char low = (*p >= 'A' && *p <= 'F') ? (*p - 'A' + 10) : (*p - '0');
        bin[(*len)++] = (high << 4) | low;
        p++;
    }
}

发送与接收数据

使用 write()read() 函数进行数据收发,发送时直接写入转换后的二进制数据,接收时需处理原始字节流并转换为 16 进制格式显示:

Linux串口收发16进制数据,如何用命令行查看与解析?

// 发送 16 进制数据
const char *hex_data = "A1 02 3F";
unsigned char bin_data[256];
int bin_len;
hex_to_bin(hex_data, bin_data, &bin_len);
write(fd, bin_data, bin_len);
// 接收数据并显示为 16 进制
unsigned char recv_buf[256];
int recv_len = read(fd, recv_buf, sizeof(recv_buf));
for (int i = 0; i < recv_len; i++) {
    printf("%02X ", recv_buf[i]);
}

使用 Python 进行串口 16 进制处理

Python 提供了 pyserial 库,简化了串口操作,安装后可通过以下代码实现 16 进制收发:

import serial
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
# 发送 16 进制数据
hex_data = "A1 02 3F"
ser.write(bytes.fromhex(hex_data))
# 接收数据并显示为 16 进制
recv_data = ser.read(ser.in_waiting or 1)
print('Received:', ' '.join(f'{b:02X}' for b in recv_data))
ser.close()

bytes.fromhex() 方法可直接将 16 进制字符串转换为字节对象,接收到的数据可通过 hex() 方法或格式化输出为 16 进制格式。

常见问题与注意事项

  1. 数据对齐问题:16 进制字符串需确保每两位对应一个字节,避免奇数长度导致解析错误。
  2. 波特率匹配:收发双方的波特率、数据位等参数必须严格一致,否则会出现乱码或数据丢失。
  3. 超时设置:合理设置串口超时时间,避免程序因等待数据而阻塞。
  4. 权限问题:确保用户对串口设备具有访问权限,可通过 ls -l /dev/ttyUSB* 检查权限。
  5. 流控处理:在高速或远距离通信时,可能需要启用硬件流控(RTS/CTS)或软件流控(XON/XOFF)。

Linux 系统下的串口 16 进制通信是嵌入式开发中的重要环节,通过 sttyxxd 等工具可快速进行调试,而 C 语言和 Python 则提供了灵活的编程接口,掌握串口配置、16 进制数据转换及收发方法,能够有效解决实际开发中的数据传输问题,在实际应用中,还需结合具体协议需求,确保数据传输的准确性和可靠性。

赞(0)
未经允许不得转载:好主机测评网 » Linux串口收发16进制数据,如何用命令行查看与解析?