Linux串口通信实战示例解析

linux 串口 例子

时间:2024-12-10 14:04


Linux串口通信:深入解析与实践案例 在当今的嵌入式系统和物联网(IoT)领域,串口通信(Serial Communication)依然扮演着举足轻重的角色

    尽管随着技术的发展,诸如USB、以太网等高速接口日益普及,但串口因其简单性、稳定性和广泛的兼容性,在调试、数据传输和低速通信等场景中仍然不可或缺

    Linux,作为一个功能强大且高度可定制的操作系统,对串口通信提供了全面的支持

    本文将深入探讨Linux下的串口通信原理,并通过一个具体实例展示如何在Linux环境下进行串口编程

     一、串口通信基础 1. 串口通信概述 串口通信,全称为串行通信接口(Serial Communication Interface),是一种将数据按位顺序传输的方式

    与并行通信相比,串口通信虽然速度较慢,但所需的连接线少,成本低,适合长距离传输,因此在许多领域得到广泛应用

     2. RS-232标准 在串口通信中,RS-232是最常见的一个电气标准

    它定义了数据信号的电压范围、极性、传输速度等参数,使得不同设备间的串口通信成为可能

    RS-232使用9针或25针的连接器,但实际应用中,常使用简化版的DB-9接口

     3. UART控制器 UART(Universal Asynchronous Receiver/Transmitter,通用异步收发传输器)是串口通信的核心组件

    它负责将并行数据转换为串行数据发送出去,同时也将接收到的串行数据转换回并行数据供处理器使用

    大多数微控制器和计算机主板都集成了UART控制器

     二、Linux下的串口通信 1. Linux串口设备文件 在Linux系统中,每个串口设备都被映射为一个设备文件,通常位于`/dev`目录下,如`/dev/ttyS0`、`/dev/ttyUSB0`等

    这些文件允许用户空间程序通过标准的文件I/O操作来访问串口

     2. termios结构体 `termios`是Linux中用于控制串口参数的一个结构体,包括波特率、字符大小、停止位、校验位等

    通过`tcgetattr`和`tcsetattr`函数可以获取和设置串口的这些参数

     3. 非阻塞与异步I/O 为了提高程序的响应性和效率,Linux提供了非阻塞I/O和异步I/O两种方式处理串口通信

    非阻塞I/O允许程序在等待串口数据时不阻塞执行,而异步I/O则允许程序在数据到达时通过回调函数处理,无需主动查询

     三、Linux串口编程实例 下面,我们将通过一个简单的C语言示例,展示如何在Linux环境下进行串口编程

    该示例将实现打开串口、配置参数、发送数据、接收数据以及关闭串口的基本功能

     1. 示例代码 include include include include include include include int set_serial_attributes(int fd, int speed) { struct termios tty; memset(&tty, 0, sizeof tty); if(tcgetattr(fd, &tty) != 0) { perror(tcgetattr); return -1; } cfsetospeed(&tty,speed); cfsetispeed(&tty,speed); tty.c_cflag= (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars tty.c_iflag &= ~IGNBRK; // disable break processing tty.c_lflag = 0; // no signaling chars, no echo, // no canonical processing tty.c_oflag = 0; // no remapping, no delays tty.c_cc【VMIN】 = 1; // read doesnt block tty.c_cc【VTIME】 = 5; // 0.5 seconds read timeout tty.c_iflag &=~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl tty.c_cflag|= (CLOCAL | CREAD); // ignore modem controls, // enable reading tty.c_cflag&= ~(PARENB | PARODD); // shut off parity tty.c_cflag |= 0; tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CRTSCTS; if(tcsetattr(fd, TCSANOW, &tty) != 0) { perror(tcsetattr); return -1; } return 0; } int main() { charportname = /dev/ttyS0; int fd =open(portname, O_RDWR | O_NOCTTY | O_SYNC); if(fd < { perror(open); return 1; } if(set_serial_attributes(fd, B9600) < 0) { // set speed to 9600 bps close(fd); return 1; } // Send data charmsg = Hello, UART! ; write(fd, msg, strlen(msg)); // Receive data charbuf【256】; int n =read(fd, buf, sizeof buf); if(n > { buf【n】 = 0; printf(Received: %sn,buf); } else if(n < { perror(read); }else { printf(No data received. ); } close(fd); return 0; } 2. 代码解析 - 打开串口:使用open函数打开指定的串口设备文件,这里使用的是`/dev/ttyS0`

    `O_RDWR`表示读写模式,`O_NOCTTY`表示不将该设备作为控制终端,`O_SYNC`表示同步读写

     - 设置串口属性:set_serial_attributes函数用于配置串口参数,包括波特率、字符大小、停止位、校验位等

    这里设置波特率为9600,8位数据位,无校验,1位停止位

     - 发送数据:使用write函数将字符串`Hello,UART!n`发送到串口

     - 接收数据:使用read函数从串口读取数据

    这里设置了一个超时机制,如果在0.5秒内没有接收到数据,`read`函数将返回

     - 关闭串口:使用close函数关闭串口设备文件

     四、总结 通过上述实例,我们展示了在Linux环境下进行串口编程的基本步骤

    从打开串口、配置参数、发送数据到接收数据,再到关闭串口,每一步都不可或缺

    理解这些基础操作,对于开发基于Linux的嵌入式系统和物联网设备至关重要

    此外,Linux提供的非阻塞I/O和异步I/O机制,为开发高性能、高响应性的串口通信应用提供了强有力的支持

    随着物联网技术的不断发展,串口通信在连接物理世界与数字世界的桥梁作用将愈发凸显,掌握Linux下的串口编程技术,将为你的技术栈增添一份宝贵的财富