一、UART简介
Universal Asynchronous Receiver Transmitter 即通用异步收发器,是一种通用的串行、异步通信总线该总线有两条数据线,可以实现全双工的发送和接收在嵌入式系统中常用于主机与辅助设备之间的通信
二、波特率
波特率用于描述UART通信时的通信速度,其单位为bps bit per second)即每秒钟传送的bit的数量
三、UART控制器
一般情况下处理器中都会集成UART控制器,我们使用UART进行通信时候只需对其内部的相关寄存器进行设置即可
四、UART硬件连接
- **TXD:**数据发送
- **RXD:**数据接收

五、UART帧格式

1、起始位:
- 是为了区分空闲状态和发送数据的状态,在发送数据前必须发送一个区别于空闲状态的信号,来通知对方(空闲状态是高电平,所以起始位只能是低电平了)
2、校验位:
- UART有三种校验,奇校验、偶校验、无校验
3、数据位:
- 5-8位数据位(先发低位,后发高位)
六、引脚功能设置
设置引脚功能的本质是让引脚在芯片内部连接到某一个对应的控制器上

七、UART控制器
UART 控制器(硬件模块)
└── 实现 UART 协议(通信标准)
├── 波特率配置
├── 帧格式(数据位/停止位/校验)
└── 红外编解码(可选功能)
1、UART 控制器(硬件组成)
| 模块 | 功能 |
|---|---|
| 波特率生成器 | 产生通信时钟(源:SCLK_UART) |
| 发送器 | Tx FIFO + 发送移位器 → TxDn |
| 接收器 | Rx FIFO + 接收移位器 ← RxDn |
| 控制单元 | 配置帧格式、使能中断等 |
2、UART 协议特性(软件可配)
-
波特率可编程
-
数据位:5/6/7/8 位
-
停止位:1/2 位
-
奇偶校验:奇/偶/无
-
红外调制(可选)
3、关系总结
UART 控制器 是硬件实现,UART 协议 是通信规则;控制器通过配置寄存器来支持协议的各种特性。
4、数据收、发过程
- 波特率发生器使用 SCLK_UART。发送器和接收器包含 FIFO 和数据移位器。
- 要传输的数据写入 Tx FIFO(发送队列),并复制到发送移位器中。
- 通过发送数据引脚(TxDn)进行移位输出。
- 接收到的数据从接收数据引脚(RxDn)移位出来,
- 并从移位器复制到 Rx FIFO 中。
八、波特率的作用
异步通信没有时钟线,靠波特率约定采样时刻,停止位周期性地重新同步,降低累积误差。
通过UBRDIV 的[0:15]位来控制波特率,波特率并不是直接写进去的,需要进行运算,
1、计算波特率:
例如,如果波特率是 115200 bps,而 SCLK_UART 为 40 MHz(实际时钟频率为100MHz),那么 UBRDIVn 和 UFRACVALn 应为:
DIV_VAL = (40000000 / (115200 × 16)) - 1
= 21.7 - 1
= 20.7
UBRDIVn = 20(DIV_VAL 的整数部分)
UFRACVALn / 16 = 0.7
(UFRACVALn 等于0.7*16,结果四舍五入)
因此,UFRACVALn = 11
九、实验过程
- 将GPA1_0和GPA1_1设置成UART2 的接收引脚和发送引脚 GPA1CON[7:0]
- 设置UART2的帧格式 8位数据位 1位停止位 无校验位 正常模式 ULCON2
- 设置UART2的接收和发送模式为轮询模式 UCON2[3:0]
- 设置UART2的波特率为115200 UBRDIV2/UFRAVAL2
十、代码
bash
#include "exynos_4412.h"
void Uart2_Init(){
//1、将GPA1_0和GPA1_1设置成UART2 的接收引脚和发送引脚 GPA1CON[7:0]
GPA1.CON=GPA1.CON &(~(0xFF)) |(0x22);
//2、设置UART2的帧格式 8位数据位 1位停止位 无校验位 正常模式 ULCON2
UART2.ULCON2=UART2.ULCON2 &(~(0x7F)) |(0x3<<0);
//3、设置UART2的接收和发送模式为轮询模式 UCON2[3:0]
UART2.UCON2=UART2.UCON2 &(~(0xF)) |(0x5<<0);
//4、设置UART2的波特率为115200 UBRDIV2/UFRAVAL2
UART2.UBRDIV2=53;
UART2.UFRACVAL2=4;
}
int main()
{
Uart2_Init();
while(1){
while(!(UART2.UTRSTAT2 & 1<<1));
UART2.UTXH2='A';
while(!(UART2.UTRSTAT2 & 1<<1));
UART2.UTXH2='b';
while(!(UART2.UTRSTAT2 & 1<<1));
UART2.UTXH2='C';
while(!(UART2.UTRSTAT2 & 1<<1));
UART2.UTXH2='d';
}
return 0;
}
十一、注意
接收端接收时不会是ABCD,这个原因是CPU向寄存器写数据的速度,与发送器向外发的速度是不一致的
