嵌入式ARM架构学习8——串口
一、单工、半双工、双工、串行、并行基础概念:
通信方式的关键分类包括:单工(单向,如广播)、半双工(双向但不同时,如对讲机)、全双工(双向同时,如电话);串行(一位一位传)与并行(多位并行传,如AHB总线)。
区分串行通信(一类概念)与串口通信(具体实现),后者是前者的子集。
1. 什么是单工、半双工、全双工通信?
这是根据数据流向对通信方式进行的分类。
单工通信:数据只能在一个方向上传输,不能反向。一方固定为发送端,另一方固定为接收端。例如:广播、电视。
半双工通信:数据可以在两个方向上传输,但不能同时进行。在某一时刻,只能有一方发送,另一方接收。就像对讲机,说话时要按住“讲话”键,此时只能发送不能接收;松开键才能听对方说话,此时只能接收不能发送。
全双工通信:数据可以在两个方向上同时、独立地传输。双方都可以同时进行发送和接收操作。例如:电话、手机通话、现代网络通信。
核心区别:关键在于数据传输方向和能否同时进行。
2. 什么是串行通信,什么是并行通信?
这是根据数据位传输方式进行的分类。
串行通信:将数据拆分成一位一位(bit),在一条信道上按顺序依次进行传输。
优点:成本低(线路少)、抗干扰能力强、适合远距离通信。
缺点:速度相对较慢(在相同时钟频率下)。
并行通信:使用多条信道,将数据的多个位(如8位、16位)同时传输出去。
优点:速度理论上是串行的数倍(在相同时钟频率下)。
缺点:成本高(线路多)、各信道间信号延迟可能导致数据错误、抗干扰能力差,不适合远距离通信。
核心区别:关键在于一次传输的数据位数和使用的信道数量。
3. 什么是异步通信,什么是同步通信?
这是根据通信双方如何协调时钟(同步) 进行的分类。
异步通信:
发送器和接收器有各自的时钟,不共享统一的时钟信号。
以字符为单位进行传输。每个字符前后加上起始位和停止位,用于标识一个字符的开始和结束,从而实现同步。
优点:实现简单,硬件成本低。
缺点:附加位(起始、停止、校验位)带来额外开销,效率相对较低。
同步通信:
通信双方共享一个统一的时钟信号(可以通过单独时钟线传输,或通过编码方式嵌入在数据流中)。
以数据帧(包含大量数据字节的块)为单位进行传输。通过特定的同步字符或同步码来标识一帧数据的开始。
优点:效率高,因为没有额外的起始/停止位开销。
缺点:硬件复杂,对时钟同步的要求非常高。
核心区别:关键在于是否共享时钟以及以何种单位(字符/帧)和方式(起始停止位/同步字符)实现同步。
4. 串口通信属于哪一类?
串口通信 通常指的是异步串行通信。
串行:数据一位一位地通过单条线路传输。
异步:通信双方使用各自的本地时钟,依靠起始位和停止位来协调每一个字节的传输。
我们常说的UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)就是实现这种通信方式的经典硬件。
5. 串口通信的电器电平标准有哪些?
串口通信的逻辑“0”和“1”需要用电平来表示,常见的电器标准有以下几种:
TTL电平:
这是芯片直接使用的电平。
逻辑 “1”:+3.3V 或 +5V
逻辑 “0”:0V
特点:电平低,易受干扰,传输距离很短(通常板卡内部或板间通信)。
RS-232标准:
这是经典的串口标准,使用负逻辑。
逻辑 “1”:-3V ~ -15V (典型值 -12V)
逻辑 “0”:+3V ~ +15V (典型值 +12V)
特点:使用较高的电压和负逻辑,抗共模干扰能力强,传输距离比TTL远(可达15米左右)。电脑后面的9针D型串口(COM口)就是此标准。
RS-485标准:
采用差分信号传输。
使用两条线 A 和 B 的电压差来表示逻辑状态。
逻辑 “1”: (A-B) < -200mV
逻辑 “0”: (A-B) > +200mV
特点:极强的抗共模干扰能力,支持多点通信(一个总线可挂多个设备),传输距离远(可达1200米以上),是工业领域广泛使用的标准。
RS-422标准:
与RS-485类似,也采用差分传输,但定义为全双工通信(需要两对差分线),且通常为一点对多点的主从式通信。
总结:TTL用于短距离,RS-232用于中距离点对点,RS-485/422用于长距离和复杂工业环境的多点通信。
二、串口通信基础概念
1、串口通信属于串行、全双工、异步通信:
- 数据按位依次传输(串行),收发线独立可同时收发(全双工),无专用时钟线,依赖双方预先约定的波特率进行同步(异步)。
2 UART通信帧结构
- 空闲态为高电平,起始位(低电平)标志传输开始,随后是8位(或7位)数据位(低位先行),可选的校验位(奇/偶/无/恒1/恒0)用于错误检测,最后是1至2位停止位(高电平)恢复空闲状态。
3.数据传输速率
- 常见的波特率有:1200、2400、4800、9600、115200(一秒钟能发送的01位数)
- 波特率指每秒传输的比特数(如115200bps),通信双方的波特率差异需控制在6%以内以确保可靠通信。
4以上的是线路高低电平的逻辑关系,但是关于物理的电气特性(电压有多高):
- TTL电平(Transistor-Transistor Logic)通常指的就是芯片引脚产生的电压,这个电压值跟选择的芯片有关,在51单片机系统下是5v;在2440下是3.3v等等。5vTTL通信距离通常被限制在几米之间,如果需要更远的距离,怎么解决呢?
- (升压)为解决这个问题IEEE(Institute of Electrical and Electronics Engineers)颁布了RS232标准,其中规定了:逻辑高电平(逻辑1):在-3V到-15V之间;逻辑低电平(逻辑0):在+3V到+15V之间收发主机间有三根线,分别是收、发和地,因此RS232是全双工的。理论上RS232能够传输20~30米。
- (差分信号)同理RS485使用两根信号线(A和B)来传输数据,通过比较A和B之间的电压差来识别信息,电压范围分别为+7V到+12V和-7V到-12V。正电压表示高电平,负电压表示低电平。这种差分信号传输方式提高了抗干扰能力。RS485的传输距离可达1200米,适用于大范围的数据传输需求。由于采用的是压差,RS485在传输数据的某一时刻,只用两根线,所以它是半双工的。
三、UART模块与硬件实现
嵌入式设备分为通信设备DCE(传感器采集)和传输设备DTE(交换机、上位机)
- UART(通用异步收发器)模块不仅支持普通串口,还兼容IRDA红外通信等其他异步串行协议,因此其寄存器众多但常用功能有限。
- 模块内部包含独立的发送(TX)和接收(RX)单元,均设有FIFO(队列)缓冲区以协调高速CPU与低速外设的数据交换,提升效率。
- DMA 直接内存访问:UART直接从RAM访问数据,释放内核
- 开发板通过CH340芯片实现USB与TTL电平的转换,利用USB接口既可进行数据通信也可供电,但推荐使用专用电源以保证稳定性和安全性。
- UART的时钟源来自IPG clock(外设时钟),而用于生成精确波特率的模块时钟(UART Clock Root)由系统时钟树提供,通常源自PLL3的480MHz时钟经分频得到。
四、UART通信参数配置
- 串口通信目标参数为115200 N 81,即波特率为115200,无校验位,8位数据位,1位停止位。
常见串口参数格式如115200N81或9600E81中各部分含义:波特率、校验类型(N无校验、E偶校验、O奇校验)、数据位数和停止位数。
传感器通信参数出厂已固定,主控设备需根据传感器手册配置相应通信参数以确保兼容性。
五、UART时钟配置
- UART模块使用IPG clock作为外设时钟(66MHz),无需修改。
- UART模块时钟根(UART clock root)来自PLL3主时钟480MHz经6分频得到80MHz,此为高速通信典型时钟。
- 确认默认配置下UART模块时钟为80MHz,适用于高速通信场景,无需额外分频设置。
六、UART寄存器配置
- 接收数据寄存器(UART_RXD)和发送数据寄存器(UART_TXD)主要用于数据读写,各使用低8位进行8位数据传输。
- 控制寄存器UCR1中的UARTEN位用于开启整个UART模块,应在所有配置完成后最后使能。
- UCR2中需设置IREN=1忽略流控引脚,PARITYEN=0关闭校验功能,STPB=0设置1位停止位,WS=1选择8位数据宽度,TXEN和RXEN分别使能发送和接收功能。
- UCR3中需将BIT2置1,这是IMX6ULL芯片UART控制器的一个特殊要求。
- 波特率生成通过UBIR和UBMR两个寄存器配合实现,根据公式计算出UBIR=999、UBMR=43401可接近115200bps目标速率。
- 状态寄存器USR2中TXDC位指示发送完成,RDR位指示接收数据就绪,编程时需轮询这些状态位以控制数据收发时序。
七、代码实现与测试
- 创建UART工程并编写初始化函数uart_init(),依次完成引脚复用、电气特性配置、软件复位及各项参数设置。
- 实现putc()发送字符函数和getc()接收字符函数,通过轮询TXDC和RDR状态位确保数据正确收发。
- 编写puts()字符串输出函数,基于putc()循环发送每个字符直至遇到字符串结束符。
- 使用串口调试助手作为上位机,验证板卡每隔一秒发送字符'a'的功能,确认通信正常。
八、标准库移植
- 将资料中的stdio文件夹复制到工程目录,包含标准输入输出头文件和源码实现。
- 修改Makefile添加include路径和lib路径,加入编译选项-fno-builtin避免内建函数冲突,指定链接库路径。
- 在UART驱动中实现空的raise()函数以满足printf异常处理需求。
- 主函数中使用scanf()和printf()成功实现数字输入计算和结果显示,验证标准库移植成功且具备回显功能。