【裸机开发】UART 串口通信(一)—— 寄存器解析

目录

一、认识 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_UBIRUARTx_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 表示要填入的发送内容

猜你喜欢

转载自blog.csdn.net/challenglistic/article/details/131435415