详解Linux下的串口
简介
串口也称串行通信接口(通常指COM接口),是实际工作中经常使用的一个接口,比如Linux下使用的debug串口,它用来登录Linux系统,输出log。另外也会使用串口和外部的一些模块通信,比如GPS模块、RS485等。串口通信的两种最基本的方式:同步串行通信方式和异步串行通信方式。异步串行是指UART(UniversalAsynchronous Receiver/Transmitter)通用异步收发传输器,通信双方接三根线,RX、TX和GND,TX用于发送数据,RX用于接受数据,双方收发交叉对接,支持全双工方式,包含TTL电平的串口和RS232电平的串口。TTL电平是3.3V的,而RS232是负逻辑电平。一般软件配置串口,有波特率,数据位、停止位、校验位、流控。分别表示传输速度,一帧数据的长度,以及发完告知停止,发完是否校验,是否进行发送控制。默认是固定8位数据位,1位停止位、无校验、无流控,只需配置波特率。【文章福利】小编推荐自己的Linux内核源码交流群:【869634926】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!前50名可进群领取,并额外赠送一份价值600的内核资料包(含视频教程、电子书、实战项目及代码)!点击下方链接即可免费领取内核相关学习资料哦
学习直通车:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈
RS-232
最常用的一种串行通讯接口。它的全名是“数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准”。传统的RS-232-C接口标准有22根线,采用标准25芯D型插头座(DB25),后来使用简化为9芯D型插座(DB9),现在应用中25芯插头座已很少采用。RS-232采取不平衡传输方式,即所谓单端通讯。由于其发送电平与接收电平的差仅为2V至3V左右,所以其共模抑制能力差,再加上双绞线上的分布电容,其传送距离最大为约15米,最高速率为20kb/s。RS-232是为点对点(即只用一对收、发设备)通讯而设计的,其驱动器负载为3~7kΩ。所以RS-232适合本地设备之间的通信。
RS-485
RS-485可以采用二线与四线方式,二线制可实现真正的多点双向通信,而采用四线连接时只能实现点对多的通信,即只能有一个主(Master)设备,其余为从设备,无论四线还是二线连接方式总线上可多接到32个设备。RS-485与RS-422的不同还在于其共模输出电压是不同的,RS-485是-7V至+12V之间,而RS-422在-7V至+7V之间,RS-485接收器最小输入阻抗为12kΩ、RS-422是4kΩ;由于RS-485满足所有RS-422的规范,所以RS-485的驱动器可以在RS-422网络中应用。RS-485与RS-422一样,其最大传输距离约为1219米,最大传输速率为10Mb/s。平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能使用规定最长的电缆长度。只有在很短的距离下才能获得最高速率传输。一般100米长双绞线最大传输速率仅为1Mb/s。
linux下的串口操作
Linux的串口表现为设备文件。串口设备文件命名一般为/dev/ttySn,若串口是USB扩展的,则串口设备文件命名多为/dev/ttyUSBn。不同的硬件平台对串口设备文件的命名有所区别。
linux终端操作串口
可使用microcom工具操作串口,如下:microcom -s 115200 /dev/ttyS1 /dev下的ttyS1对应的就是UART1设备。 microcom 命令后的-s 115200,表示设置波特率为115200bps。 micrcom指令退出的方式是Ctrl+x,不是Ctrl+c。
打开串口
在编写Linux串口程序时,需要包含termios.h头文件:
在使用某个串口前,必须用open()函数打开它所对应的设备文件。如下:
当open调用成功后,将返回文件描述符,并作为其它操作函数的参数;如果失败返回负数。在打开串口时,除了需要用到O_RDWR选项标志外,通常还需要使用O_NOCTTY,目的是告诉Linux“本程序不作为串口的‘控制终端’”。如果不使用该选项,会有一些输入字符影响进程运行(如一些产生中断信号的键盘输入字符等)。
关闭串口
当不再使用某个串口时,可用close()函数关闭串口:close(fd); 参数fd为打开串口时得到的文件描述符。
发送数据
往串口发送数据可通过write()函数完成。
字符串的长度为sizeof(buf),作为write()函数的发送数据长度参数。写操作完成后,返回值为成功发送数据的长度;如果发送失败,返回负数。
设置串口参数
串口通讯波特率设置
波特率的设置定义在<termios.h>里。设置波特率使用cfsetispeed( )和cfsetospeed( )函数来操作,波特率信息是通过cfgetispeed()和cfgetospeed()函数来完成的。
一般来说,输入、输出的波特率应该是一致的。
串口属性配置
属性定义在结构体struct termios中。头文件<termbits.h>
该结构体定义如下:
VTIME 和 VMIN
VTIME 定义要求等待的零到几百毫秒的值(通常是一个8位的unsigned char变量)。
VMIN 定义了要求等待的最小字节数, 这个字节数可能是0。只有设置为阻塞时这两个参数才有效,仅针对于读操作。
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
VMIN = 0,当缓冲区字节数 >= 0 时进行读操作,实际上这时读串口操作并未被阻塞,因为条件始终被满足。
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 1;VMIN = 1,当缓冲区字节数 >= 1 时进行读操作,当没有数据时读串口操作被阻塞。options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 4;
VMIN = 4,当缓冲区字节数 >= 4 时进行读操作,否则读串口操作被阻塞。每次读出的最大字节数由read函数中第三个参数决定。直到缓冲区剩下的数据< read 第三个参数 并且< 4 (如果这时read第三参数为 1 则进行4次读操作直至读完缓冲区,如read第三参数为2,连续进行读操作,直至缓冲区空或还剩一个字符)。没有设置VTIME,剩下的字符没有确定的期限,直到下次满足读条件的时候才被读出。
options.c_cc[VTIME] = 10; //单位百毫秒
options.c_cc[VMIN] = 4;同3的区别就是,没满足条件或读缓冲区中剩下的数据会在1秒(10百毫秒)后读出。另外特别注意的是当设置VTIME后,如果read第三个参数小于VMIN ,将会将VMIN 修改为read的第三个参数,即,使用read(fd,&buf,2);,以上设置变为:
options.c_cc[VTIME] = 10;
options.c_cc[VMIN] = 2;
读取数据
使用read()函数可以读取串口接收到的数据。
读取成功,函数返回所读数据长度;失败返回负数。
使用范例
原文参考:https://mp.weixin.sigusoft.com/s/Zdr6rRHUYZPuF148JiXnsQ
往期回顾:
最新干货!使用eBPF LSM热修复Linux内核漏洞
深度剖析Linux内核通用链表与内存池的使用
盘点那些Linux内核调试手段——内核打印
Linux 环境下网络分析和抓包是怎么操作的?
浅谈ARM64Linux内核页表的块映射
吐血爆肝!Linux面试常见问题分享(建议收藏!)
搞嵌入式开发,有哪些经典的开源项目值得学习?
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/91753.html