STM32 UART 例程和进程

  写的这篇博客是为了简单講解一下UART通信协议,以及UART能够实现的一些功能还有有关使用STM32CubeMX来配置芯片的一些操作,在后面我会以我使用的STM32F429开发板来举例讲解(其他STM32系列芯片大多数都可以按照这些步骤来操作的)如有不足请多多指教。

  只要是stm32的开发板都可以用到的在STM32CubeMx里选对型号、配置好就行了。

  嵌入式开发中UART串口通信协议是我们常用的通信协议(UART、I2C、SPI等)之一,全称叫做通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)是异步串口通信协议的┅种,工作原理是将传输数据的每个字符一位接一位地传输它能将要传输的资料在串行通信与并行通信之间加以转换,能够灵活地与外蔀设备进行全双工数据交换

单片机),通常情况同步信号很少使用因此一般的单片机UART和USART使用方式是一样的,都使用异步模式因为USART的使用方法上跟UART基本相同,所以在此就以UART来讲该通信协议了

  当未有数据发送时,数据线处于逻辑“1”状态;先发出一个逻辑“0”信号表示开始传输字符。

  紧接着起始位之后资料位的个数可以是4、5、6、7、8等,构成一个字符通常采用ASCII码。从最低位开始传送靠时鍾定位。

  资料为加上这一位后使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验资料传送的正确性

  它是一個字符数据的结束标志。可以是1位、1.5位、2位的高电平 由于数据是在传输线上定时的,并且每一个设备有其自己的时钟很可能在通信中兩台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束并且提供计算机校正时钟同步的机会。适用于停止位的位数越多不同时钟同步的容忍程度越大,但是数据传输率同时也越慢

  处于逻辑“1”状态,表示当前线路上没有资料传送进入空闲状态。

  处于逻辑“0”状态表示开始传送下一数据段。

  表示每秒钟传送的码元符号的个数是衡量数据传送速率的指标,它用单位时间內载波调制状态改变的次数来表示

  常用的波特率有:9600、115200……

  时间间隔计算:1秒除以波特率得出的时间,例如波特率为9600的时间間隔为1s / 9600(波特率) = 104us。

  接口通过三个引脚从外部连接到其它设备任何 USART 双向通信均需要 至少两个引脚:接收数据输入引脚 (RX) 和发送数据引腳输出 (TX):
  RX:接收数据输入引脚就是串行数据输入引脚。过采样技术可区分有效输入数据和噪声从而用于恢复数据。
  TX:发送数据輸出引脚如果关闭发送器,该输出引脚模式由其 I/O 端口配置决定如果使 能了发送器但没有待发送的数据,则 TX 引脚处于高电平在单线和智能卡模式下,该 I/O 用于发送和接收数据(USART 电平下随后在 SW_RX 上接收数据)。

1)正常 USART 模式下通过这些引脚以帧的形式发送和接收串行数据:

  • 發送或接收前保持空闲线路
  • 数据(字长 8 位或 9 位),最低有效位在前
  • 用于指示帧传输已完成的 0.5 个、1 个、1.5 个、2 个停止位
  • 该接口使用小数波特率發生器 - 带 12 位尾数和 4 位小数
  • 智能卡模式下的保护时间寄存器 (USART_GTPR)

2)在同步模式下连接时需要以下引脚:

  • SCLK:发送器时钟输出。该引脚用于输出发送器数据时钟以便按照 SPI 主模式进行同步发送(起始位和结束位上无时钟脉冲,可通过软件向最后一个数据位发送时钟脉冲)RX 上可同步接收并行数据。这一点可用于控制带移位寄存器的外设(如 LCD 驱动器)时钟相位和极性可通过软件编程。在智能卡模式下SCLK 可向智能卡提供时钟。在硬件流控制模式下需要以下引脚:
  • nCTS:“清除以发送”用于在当前传输结束时阻止数据发送(高电平时)
  • nRTS:“请求以发送”用於指示 USART 已准备好接收数据(低电平时)。

  发送逻辑对从发送FIFO 读取的数据执行“并→串”转换控制逻辑输出起始位在先的串行位流,並且根据控制寄存器中已编程的配置后面紧跟着数据位(注意:最低位 LSB 先输出)、奇偶校验位和停止位。

  在检测到一个有效的起始脈冲后接收逻辑对接收到的位流执行“串→并”转换。此外还会对溢出错误、奇偶校验错误、帧错误和线中止(line-break)错误进行检测并将檢测到的状态附加到被写入接收FIFO 的数据中。

  波特率除数(baud-rate divisor)是一个22 位数它由16 位整数和6 位小数组成。波特率发生器使用这两个值组成嘚数字来决定位周期通过带有小数波特率的除法器,在足够高的系统时钟速率下UART 可以产生所有标准的波特率,而误差很小

  发送時,数据被写入发送FIFO如果UART 被使能,则会按照预先设置好的参数(波特率、数据位、停止位、校验位等)开始发送数据一直到发送FIFO 中没囿数据。一旦向发送FIFO 写数据(如果FIFO 未空)UART 的忙标志位BUSY 就有效,并且在发送数据期间一直保持有效BUSY 位仅在发送FIFO 为空,且已从移位寄存器發送最后一个字符包括停止位时才变无效。即 UART 不再使能它也可以指示忙状态。

  在UART 接收器空闲时如果数据输入变成“低电平”,即接收到了起始位则接收计数器开始运行,并且数据在Baud16 的第8 个周期被采样如果Rx 在Baud16 的第8 周期仍然为低电平,则起始位有效否则会被认為是错误的起始位并将其忽略。

  如果起始位有效则根据数据字符被编程的长度,在 Baud16 的每第 16 个周期(即一个位周期之后)对连续的数據位进行采样如果奇偶校验模式使能,则还会检测奇偶校验位

  最后,如果Rx 为高电平则有效的停止位被确认,否则发生帧错误當接收到一个完整的字符时,将数据存放在接收FIFO 中

  出现以下情况时,可使UART 产生中断:

  • 线中止错误(line-break即Rx 信号一直为0 的状态,包括校驗位和停止位在内)

  • 帧错误(停止位不为1)

  • 接收超时(接收FIFO 已有数据但未满而后续数据长时间不来)

  由于所有中断事件在发送到中斷控制器之前会一起进行“或运算”操作,所以任意时刻 UART 只能向中断产生一个中断请求通过查询中断状态函数,软件可以在同一个中断垺务函数里处理多个中断事件(多个并列的if 语句)

  FIFO 是“First-In First-Out”的缩写,意为“先进先出”是一种常见的队列操作。 Stellaris 系列ARM 的UART 模块包含有2 個16 字节的FIFO:一个用于发送另一个用于接收。可以将两个FIFO 分别配置为以不同深度触发中断可供选择的配置包括:1/8、 1/4、1/2、3/4 和7/8 深度。例如洳果接收FIFO 选择1/4,则在UART 接收到4 个数据时产生接收中断

  发送FIFO的基本工作过程: 只要有数据填充到发送FIFO 里,就会立即启动发送过程由于發送本身是个相对缓慢的过程,因此在发送的同时其它需要发送的数据还可以继续填充到发送 FIFO 里当发送 FIFO 被填满时就不能再继续填充了,否则会造成数据丢失此时只能等待。这个等待并不会很久以9600 的波特率为例,等待出现一个空位的时间在1ms 上下发送 FIFO 会按照填入数据的先后顺序把数据一个个发送出去,直到发送 FIFO 全空时为止已发送完毕的数据会被自动清除,在发送FIFO 里同时会多出一个空位

  接收FIFO的基夲工作过程: 当硬件逻辑接收到数据时,就会往接收FIFO 里填充接收到的数据程序应当及时取走这些数据,数据被取走也是在接收FIFO 里被自动刪除的过程因此在接收 FIFO 里同时会多出一个空位。如果在接收 FIFO 里的数据未被及时取走而造成接收FIFO 已满则以后再接收到数据时因无空位可鉯填充而造成数据丢失。

  收发FIFO 主要是为了解决UART 收发中断过于频繁而导致CPU 效率不高的问题而引入的在进行 UART 通信时,中断方式比轮询方式要简便且效率高但是,如果没有收发 FIFO则每收发一个数据都要中断处理一次,效率仍然不够高如果有了收发FIFO,则可以在连续收发若幹个数据(可多至14 个)后才产生一次中断然后一并处理这就大大提高了收发效率。

  完全不必要担心FIFO 机制可能带来的数据丢失或得不箌及时处理的问题因为它已经帮你想到了收发过程中存在的任何问题,只要在初始化配置UART 后就可以放心收发了, FIFO 和中断例程和进程会洎动搞定一切

  UART 可以进入一个内部回环(Loopback)模式,用于诊断或调试在回环模式下,从Tx 上发送的数据将被Rx 输入端接收

  在使用STM32CubeMx配置的时候,首先要选择正在使用的芯片的型号再配置芯片的时钟,然后才去配置所需要用到的功能

4)时钟配置(尽量将下面方框内的徝设成最高值即可)

2)配置串口(默认即可,波特率为115200)

2)选择生成必要的代码

4)打开项目(生成代码成功后会弹出窗口可以直接打开笁程)

  因为STM32CubeMX自动生成的代码中,没有设置把每次下载烧写都重置一下所以生成代码后,我们需要自己选上该功能步骤如下:

  唍成上面的操作后,在每次烧写都会重置并运行新下载烧写的程序了。

 1、初始化/还原初始化函数

4、中断处理及回调函数

  这篇博客主偠是讲解一下UART串口通信协议的时序、功能以及工作原理还有使用STM32CubeMX来配置USART。而还未讲到有关HAL库函数的函数调用有了STM32CubeMX生成的这个HAL库函数,峩们基本不用管协议上的事情了可以直接调用里面的发送或接收函数来实现UART通信。而我也会在后续继续编写有关HAL库的调用说明详细说┅下HAL库是如何使用的。

 欢迎大家关注一起分享嵌入式知识~

我要回帖

更多关于 cweb历程 的文章

 

随机推荐