目录
一、认识 UART
1、概念
2、帧格式
二、IO 复用为 UART 寄存器解析
1、原理图分析
2、寄存器解析
三、UART 相关寄存器解析
1、UART1_UCR1~4
2、UART1_USR1~2
3、波特率配置
4、UART1_URXD
5、UART1_UTXD
一、认识 UART
1、概念
UART 是一种通用的串行、异步通信总线,该总线有两条数据线,TXD 用于发送数据,RXD用于接收数据,可以实现全双工的发送和接收,在嵌入式系统中常用于主机与辅助设备之间的通信。
2、帧格式
UART帧格式如下:
空闲位:没有任何数据的传输(默认维持在高电平)
起始位:表示要开始发送数据了,此时会变为低电平
数据位:一般有8位,代表一个字节。
校验位:方便接收方核对数据是否被篡改(可有可无)
停止位:表示一帧数据的结束。相当于告知对方数据发送完毕,重新回到高电平(空闲状态)
二、IO 复用为 UART 寄存器解析
既然涉及到 IO,那就需要考虑配置引脚复用为 UART 功能。
1、原理图分析
首先在底板原理图中找到 USB USART 模块,现在电脑上更多的还是 USB 接口,所以便催生出了许多串口TTL转USB 的芯片(如CH340、PL2303)
然后我们再去核心板找一下 UART1_RXD 和 UART1_TXD 连接到了核心板的哪两个引脚。
因此,我们需要找到和 UART1 相关,而且和 TXD、RXD 相关的寄存器。
2、寄存器解析
既然涉及到引脚复用,那就涉及到复用配置和电气属性配置。
- IO 复用
- IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA
- IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA
- 配置电气属性
- IOMUXC_SW_PAD_CTL_PAD_UART1_TX_DATA
- IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA
/************ 配置 IO 复用 **********/
寄存器: IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA
基地址: 0x20E0084
初始化操作:
IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA &= ~(0xF);
寄存器: IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA
基地址: 0x20E0088
初始化操作:
IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA &= ~(0xF);
/************ 配置电气属性 **********/
// 主要参考之前 LED 的电气属性配置
寄存器: IOMUXC_SW_PAD_CTL_PAD_UART1_TX_DATA
基地址: 0x20E0310
初始化操作:
IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA = 0x10B0;
寄存器: IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA
基地址: 0x20E0314
初始化操作:
IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA = 0x10B0;
电气属性配置参考:LED 驱动寄存器解析
三、UART 相关寄存器解析
下面是和 UART 初始化相关的寄存器:
- UARTx_UCR1~4:串口配置寄存器。串口使能、数据位位数、停止位位数等。
- UARTx_USR1~2:串口状态寄存器。可用于判断是否接收到数据、数据是否发送完毕等。
- UARTx_UFCR、UARTx_UBIR、UARTx_UBMR:搭配使用,用于配置波特率
和 UART 实际应用相关的寄存器:
- UARTx_URXD:保存接收到的数据、接收是否存在错误等
- UARTx_UTXD:保存用于发送的数据
1、UART1_UCR1~4
UARTx_UCR1:
① bit 0:UART 关闭 / 使能。(0:禁止 1:使能)
② bit 14:自动检测波特率使能。这里设为禁止,因为后面我们会通过寄存器手动设置波特率
UARTx_UCR2:
① bit 0:软复位。重置发射机、接收机、所有的FIFO以及相关寄存器。
② bit 1:接收机使能(接收数据使能。0:禁止 1:使能)
③ bit 2:发射机使能(发送数据使能。0:禁止 1:使能)
④ bit 5:设置数据位长度(不含起始位、停止位、校验位。0:数据位为7位 1:数据位为8位)
⑤ bit 6:设置停止位长度(0:停止位为1位 1:停止位为2位)
⑥ bit 7:设置奇偶校验(0:偶校验 1:奇校验)
⑦ bit 8:校验使能(0:禁止 1:使能)
⑧ bit 14:是否无视RTS引脚(0:使用RTS引脚 1:无视RTS引脚)
UARTx_UCR3:
① bit 2:复用选择。如果UART是某个引脚复用的,那么该位需要被置1
UARTx_UCR4(没有需要配置的位)
寄存器: UART1_UCR1
基地址: 0x2020080
初始化操作:
/*
* bit 0: 0 初始禁止(等其他寄存器配置完了再使能)
* bit 14: 0 禁止自动检测波特率
*/
UART1_UCR1 &= ~(1 << 0);
UART1_UCR1 &= ~(1 << 14);
寄存器: UART1_UCR2
基地址: 0x2020084
初始化操作:
/*
* bit 0: 0 软复位(放在其他配置之前,等待软复位结束再配置其他寄存器)
* bit 1: 1 接收使能
* bit 2: 1 发送使能
* bit 5: 1 数据位为 8 bit
* bit 6: 0 停止位占 1 bit
* bit 8: 0 关闭奇偶校验
* bit 14: 1 无视RTS引脚(无需硬件流控)
*/
UART1_UCR2 &= ~(1 << 0);
while((UART1_UCR2 & 0x01) == 0); // 等待软复位结束
UART1_UCR2 |= ((1 << 1) | (1 << 2) | (1 << 5) | (1 << 14));
UART1_UCR2 &= ~((1 << 6) | (1 << 8));
寄存器: UART1_UCR3
基地址: 0x2020088
初始化操作:
UART1_UCR3 |= (1 << 2); // 只要被复用为 UART1 功能,该位需置1
寄存器: UART1_UCR4
基地址: 0x202008C
2、UART1_USR1~2
这里我们主要关注的是 UARTx_USR2 中的 bit 0 和 bit 3
- bit 0:数据是否准备就绪(是否接收到数据)
- bit 3:数据是否发送完毕
寄存器: UART1_USR2
基地址: 0x2020098
3、波特率配置
波特率的计算公式如下。主要涉及到以下三个寄存器,我们主要设置的是:
- UARTx_UFCR:设置 uart 时钟的分频数。
- UARTx_UBIR:bit 15-0
- UARTx_UBMR:bit 15-0
(1) Ref Freq
UART 的时钟源来自系统时钟PLL3(480MHz),经过 6 分频和 1 分频以后,得到的uart_clk = 80MHz。
UART 内部还可以再次分频,最终得到的就是 Ref Freq
(2) 寄存器配置
假设我们要设置的波特率是 115200,内部不分频(UARTx_UFCR = 1),因此,接下来需要确定的是 UBMR 和 UBIR。直接公布答案,数字是凑出来的。
- UARTx_UFCR = 1
- UBIR = 71
- UBMR = 3124
寄存器: UART1_UFCR
基地址: 0x2020090
初始化操作:
/*
* bit 9-7: 101 分频数为1
*/
UART1_UFCR &= ~(7 << 7);
UART1_UFCR |= (5 << 7);
寄存器: UART1_UBIR
基地址: 0x20200A4
初始化操作:
UART1_UBIR = 0;
UART1_UBIR = 71;
寄存器: UART1_UBMR
基地址: 0x20200A8
初始化操作:
UART1_UBMR = 0;
UART1_UBMR = 3124;
4、UART1_URXD
寄存器: UART1_URXD
基地址: 0x2020000
获取接收数据: UART1_URXD & 0xFF
5、UART1_UTXD
寄存器: UART1_UTXD
基地址: 0x2020040
设置发送内容:
UART1_UTXD &= ~0xFF; // 低 8 位清零
UART1_UTXD |= val; // val 表示要填入的发送内容