Skip to content
On this page

UART串口实验(Cortex-A7)


标签:FSMP1A/🧪实验  

🎯UART和USART串口

  • 总线的概念
  • UART(Universal Asynchronous Receiver/Trainsmitter) 通用异步收发传输器
  • USART(Universal Asynchronous/Asychronous Receiver/Trainsmitter) 通用同步/异步收发传输器
  • 都是串行通信接口

🔌串口的连接方式

1. 直连方式

excalidraw/FSMP1A_调试串口.png

2. usb 转串口连接方式

txt
RS232电平:
  高电平:-----> + 5v
  低电平:-----> + 0v
TTL电平:
  高电平:-----> +15v ~ +3v
  低电平:-----> -15v ~ -3v

  1. 仿真器的作用:完成 USB 口和串口之间的切换
  2. 在 ST-LINK 仿真器内部有一个 STM32F103 芯片,在这个芯片内固化了一段代码,这段代码完成 USB 口和串口之间的转换

📝串口的通信协议

串口常用配置

  • 下图为 SecureCTR 程序连接串行设备的配置界面:

  1. 串口采用的是串行通信方式:因为收发数据时,一个时钟周期,只能收发一位数据
  2. 串口常用配置信息:
    • 波特率:115200 单位 bps (比特率、 二进制/秒、比特/秒)
      • 含义:串口通信时,传输的速率,1s 钟可以传输 115200bit 数据
      • 115200 的倒数代表传输每位数据需要的时间
    • 数据位:8 位数据位
    • 校验位:没有
    • 停止位:1

串口通信协议

  1. 空闲态:总线处于高电平状态,UART 总线不在传输数据时,总线就处于空闲状态
  2. 起始信号:总线处于低电平状态,开始发送数据的标志
  3. 数据位:总线处于高/低电平状态,要看实际发送的数据,先发送低位,再发送高位
  4. 校验位(奇校验/偶校验)
    • 奇校验:数据位和校验位 1 的个数为奇数
      • 假设发送数据 0x55,校验位:1
      • 假设发送数据 0x51,校验位:0
    • 偶校验:数据位和校验位 1 的个数位偶数
      • 假设发送数据 0x55,校验位:0
      • 假设发送数据 0x51,校验位:1
    • 实际开发中很少使用校验位,因为会占用掉 1 帧数据影响传输的速率
  5. 终止信号:发送数据结束,校准时钟信号

🤔思考:一帧数据发送完成后,为什么需要校准时钟信号?

  1. 因为串口采用的是异步通信方式,双方都有自己独立的时钟源,需要设置双方时钟源保持一致
  2. 但是在发送数据后,每发送完一帧数据,都会产生误差,越往后误差越大,发送或者接收数据不准确
  3. 所以每发送完一帧数据,需要校准时钟源

⚡分析电路图

  • FSMP1A主板的丝印上的 J12 找到对应的原理图:

  • 上图中,最右边的 1,2,3 对应的是 TXD,RXD 和 GND
  • 最左边是网络标号 UART4_TXUART4_RX

  • 通过网络标号,找到它们的引脚分别是 PB2PG11

🕵️分析框图

excalidraw/STM32MP157_UART分析框图.png

  • (RCC 章节)需要通过 RCC 使能 GPIOGGPIOB 以及 UART4 控制器
  • (GPIO 章节)需要:
    1. 将引脚设置为复用功能模式
    2. 设置复用功能模式为串口模式
  • (UART 章节)需要:
    1. 串口初始化相关工作
    2. 数据收发

1️⃣分析RCC章节

  • 目的:通过 RCC 使用 GPIOG/GPIOEUART4 控制器
  • 通过 2.5.2 章节可知,RCCGPIO 组相关的控制器,通过『 AHB4 』总线与 A7 核相连

  • URAT 则通过 APB1 总线和 A7 核相连:

  • 通过 AHB4 总线的部分,可以知道它们的基地址分别是:
    • GPIOG0x50008000
    • GPIOB0x50003000
    • RCC: 0x50000000

  • 通过 APB1 总线的部分,可以知道 UART 的基地址为 0x40010000

  • 使用 AHB4 的使能寄存器 AHB4ENSETR,将 GPIOBGPIOERCC 控制器使用:
  • RCC 的基地址是 0x5000_0000 偏移后为 0x5000_0A28 为该寄存器地址
  • 因为需要使用这两个 GPIOBGPIOE 所以,将第 1 和第 6 位设置为 1

  • 同理,在 APB1 的使能寄存器中 APB1ENSETR,启用 UART4 控制器:
    • 它的地址是 RCC基地址 + 偏移量 = 0x5000_0000 + 0xA00 = 0x5000_0A00
  • 将它的第 16 位设置为 1 使用 UART4 控制器

2️⃣分析GPIO章节

  • 目的:将引脚设置为复用功能模式,设置复用功能模式为串口模式

GPIO_xMODER 寄存器

  • 该寄存器为端口模式寄存器,作用设置 GPIO 引脚模式
  • 第一步:确定地址
    • GPIOB_MODER地址 = GPIOB基地址 + 偏移地址 = 0x5000_3000 + 0x00 = 0x5000_3000
    • GPIOG_MODER地址 = GPIOG基地址 + 偏移地址 = 0x5000_8000 + 0x00 = 0x5000_8000
  • 第二步:通过 GPIOB_MODER 寄存器设置 PB2 引脚为复用功能模式:
    • GPIOB_MODER[5:4] = 0b10
    • 0x5000_3000[5:4] = 0b10
  • 第三步:通过 GPIOG_MODER 寄存器设置 PG11 引脚为复用功能模式:
    • GPIOG_MODER[23:22] = 0b10
    • 0x50008000[23:22] = 0b10

GPIOx_AFRL 寄存器和 GPIOx_AFRH 寄存器

  • Alternative Function (AF)
  • 复用功能选择寄存器有两个,分别是 GPIOx_AFRLGPIOx_AFRH,因为每个引脚需要通过 4 位进行设置,所以分低(引脚0-7)和高(引脚8-15)

  • 寄存器允许写入的数据如下:

  • 至于需要填入的 AF 编号,需要参考 DS12504-STM32MP157 的 datasheet 文档
  • 在上述文档的第四章节的『引脚描述和功能复用』中的 Table.9 找到 引脚 PB2 行,找到表中的 UART4_RX 功能,可以看到它属于 AF8 一列,所以我们需要在上述的 GPIOB_AFRL 寄存器中填入 AF8 对应的 0b1000

  • 同理,在 GPIOx_AFRH 部分的文档中,我们需要修改的是 12-15 四个位:

  • 在 DS12504 文档第四章中找到对应的 AF 编号:

  • 返回寄存器文档,查看需要填入的四位:

🚀总结

  1. GPIO_xMODER 修改引脚功能,GPIOx_AFRLGPIOx_AFRH 寄存器修改引脚对应的复用功能
  2. 为什么 GPIO 章节中有两个复用功能寄存器?
    • 因为每个 GPIO 有 16 个引脚编号
    • GPIOx_AFRL 寄存器每 4 位管理一个引脚,一个寄存器 32 位
  3. GPIOx_AFRL 寄存器设置
    • GPIOB_AFRL = 基地址 + 偏移地址 = 0x5000_3000 + 0x20 = 0x5000_3020
    • GPIOB_AFRL[11:8] = 0b1000
  4. GPIOx_AFRH 寄存器设置
    • GPIOB_AFRH = 基地址 + 偏移地址 = 0x5000_8000 + 0x20 = 0x5000_8020
    • GPIOB_AFRH[12:15] = 0b0110

3️⃣分析UART章节

  • 对应 RM0436 文档第 53 章节

功能框图

  • 分析 UART/USART 的框图:

数据发送流程

  • 在 53.5.5 USART transmitter 章节,可以找到 Character transmission procedure

🚀 总结

  1. USART_CR1 寄存器设置数据位的宽度,设置串口使能,设置 TE 位使能
  2. USART_CR2 寄存器设置停止位
  3. USART_BRR 寄存器设置波特率
  4. USART_TDR 寄存器串口发送数据
  5. 标志位(用来读取检查,不是用来设置):
    • TXE:数据有没有写到发送数据寄存器中
    • TC:一帧数据是否发送完成

数据接收流程

  • 和数据发送流程类似,上面是数据的接收流程
  • 通过 USART_CR1 寄存器设置数据位
  • 通过 USART_BRR 寄存器设置波特率
  • 通过 USART_CR2 寄存器设置停止位
  • USART_CR1 寄存器的 UE 位设置为 1
  • 设置 USART_CR1RE 位使能,这是数据接收的起始位

USART_CR1 寄存器

  • 目标:地址 + 设置的位 + 设置值
  • UART4 的基地址,参考分析 RCC 章节0x4001_0000

M1 位和 M0 位

  • 设置 1 位起始位,8位数据位

OVER8 位

  • 采样率,影响波特率设置的值,越大越准确

PCE 位

  • 设置无奇偶校验位

TE位

  • 设置发送位使能

RE位

  • 设置接收位使能

UE位

  • 设置串口使能

🚀 USART_CR1 寄存器总结

  • USART_CR1 寄存器的功能是设置串口的初始化
  • 地址:0x4001_0000 + 0x00 = 0x4001_0000
    • USART_CR1[28][12] = 00 -------> 设置8位数据位
    • USART_CR1[15] = 0 -------> 设置16倍采样率
    • USART_CR1[10] = 0 -------> 设置串口无奇偶校验位
    • USART_CR1[3] = 1 -------> 设置串口发送器使能
    • USART_CR1[2] = 1 -------> 设置串口接收器使能
    • USART_CR1[0] = 1 -------> 设置串口使能

USART_CR2 寄存器

  • 设置串口的停止位
  • 地址 0x4001_0000 + 0x04
  • 初始化数值:CR2[13][12] = 0b00

  • 只有 USART 关闭的时候才能有效(UE 位为 0)

USART_BRR 寄存器

  • 上图为 BRR 寄存器的文档,它的地址是 0x4001_0000 + 0x0c
  • 需要设置的是 [0:15],它是依据 53.5.7 的公式进行计算

  • 上图为一个例子,比如 9600 波特率,使用的采样率是 16 倍,通过公式计算,得到的 BRR 需要设置的为 0341h
  • 如果想知道 USART_BRR 寄存器需要设置的值,需要参考 53.5.7 章节,确认串口提供的主频64MHZ(这是 uboot 设置的),并且设置波特率为 115200
    • USART_BRR = 64000000 / 115200 = 0x22B

USART_RDR 寄存器

  • 串口接收数据寄存器
  • 地址 0x4001_0024
  • 接收到的数据存放在串口数据寄存器中,只能读不能写
  • RDR[8:0] :接收到的数据

USART_TDR 寄存器

  • 串口发送数据寄存器
  • 地址:0x4001_0028
  • 将发送的数据按位发送到发送寄存器中
    • TDR[8:0] = 要发送的数据

USART_PRESC 寄存器

  • 时钟分频寄存器,分频影响主频从而影响波特率的生成(看功能框图
  • 地址:0x4001_002C
  • 因为前面设置好了 BRR 寄存器,所以这里设置不分频
  • PRESC[3:0] = 0b0000

USART_ISR 寄存器

  • 状态寄存器,用来读取 UART 的状态
  • 地址 0x4001_001C

  • 读取 TXE 位,可以 判断发送寄存器空满
  • UART4_ISA[7],只有空才能发送下一个字节数据,如果满需要等待

  • 读取 TC 位,可以判断数据是否完成

  • 读取 RXNE 位,可以判断接收寄存器的是否为空

🧪实验1

Task

  1. 在键盘输入一个字符,串口工具进行显示
  2. 例如,在键盘输入一个字符 a,串口工具显示 b

🧪实验2

Task

  1. 在键盘输入一个字符串,串口工具进行显示
  2. 例如,在键盘输入一个字符串 "huyue",串口工具进行显示 "huyue"

Last updated: