STM32串口通信学习总结

                                                                         STM32串口通信学习总结

1.概述

1.1学习目的

通过基于AWA5812平台,学习STM32F767芯片的串口通信程序开发。本人学习串口通信比较曲折,一开始使用的芯片时STM32新开发出来的一块STM32L496ZG的板子,这块板子的优点时低功耗,性能在M4系列中也比较强大,满足了公司对现有产品升级的需求,而对于我这个新入手不到一个月的职场小白来说,这块板子时相对的不友好了,所先从资料来说除了其芯片手册,参考手册,数据手册,STM32官网包括论坛就几乎没有其他资料,而且全是英文,曾看到论坛的人在喊说大家一起来翻译中文版吧,一人一段,看似很令人兴奋的事,可这也说明现在是别想指望由中文版的了,所以只有硬着头皮上吧;其次STM32官方给的例程在板子上没跑通,这就奇了怪了,例程能错嘛?坚持了2周我果断实现了从入门到放弃的过程。可工作要求实在没办法,煎熬了一周,果断向正点原子爸爸靠拢,花了千元买了块阿波罗F767开发板,毫无疑问,正点原子爸爸给视频给例程还给中文参考手册,手把手教你编程,百度以下所遇到的问题,只应证了一点,你经历的别人都经历过。好的话不多说,来讲讲我的STM32串口通信的学习历程吧。

1.2.学习过程

接下来我将从以下几个方面介绍我学习过程

1、物理层

2、通用同步异步收发器

3、STM32串口通信过程

4、串口配置的一般步骤及代码分析

5、问题总结

1.3参考文档

《STM32F767xx数据手册》

《STM32F4开发指南 v1.1 HAL库版本》

《RM0385参考手册》

  1. 物理层

2.1通讯标准说明

串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,大部分电子设备都支持该通讯方式,我们在调试设备时也经常使用该通讯方式输出调试信息。

STM32串口通信学习总结

串口通信的物理层主要在两设备间,主要用的标准是RS-232标准,它规定了信号的用途、通讯接口及信号的电平水平。

2.2 DB9接口中的公头及母头的各引脚示意图

STM32串口通信学习总结

2.3 ST-Link/v2接口说明

2.3.1 LED状态说明:

闪烁红色:ST-LINK/V2连接到计算机后,第一次USB枚举过程

红色:ST-LINK/V2与计算机已建立连接

闪烁绿色/红色:目标板和计算机在进行数据交换

绿色:通讯完成

橙色(红色+绿色):通讯失败

2.3.2 STM8接口定义

仿真端口

连接目标板

功能

1、VDD

MCU VCC

连接STM8目标板的电源VCC

2、DATA

MCU SWIM

连接STM8目标板的SWIM PIN

3、GND

GND

连接STM8目标板的电源GND

4、RESET

MCU RESET PIN

连接STM8目标板的RESET PIN

排列示意图如下

STM32串口通信学习总结

2.3.3 STM32接口定义

仿真器端口

连接目标板

功能

1. TVCC

MCU电源VCC

连接STM32目标板的电源VCC

2. TVCC

MCU电源VCC

连接STM32目标板的电源VCC

3. TRST

GND

GROUND

4. UART-RX

GND

GROUND

5. TDI

TDI

连接STM32的JTAG TDI

6. UART-TX

GND

GROUND

7. TMS, SWIO

TMS, SWIO

连接STM32的JTAG的TMS, SWD的SW IO

8. BOOT0

GND

GROUND

9. TCK, SWCLK

TCK, SWCLK

连接STM32的JTAG的TCK, SWD的SW CLK

10. SWIM

GND

GROUND

11. NC

NC

Unused

12. GND

GND

GROUND

13. TDO

TDO

连接STM32的JTAG TDO

14. SWIM-RST

GND

GROUND

15. STM32-RESET

RESET

连接STM32目标板的RESET端口

16. KEY

NC

GROUND

17. NC

NC

Unused

18. GND

GND

GROUND

19. VDD

NC

VDD (3.3V)

20. GND

GND

GROUN

排列示意图

STM32串口通信学习总结

  1. 通用同步异步收发器

通用同步异步收发器是一个串行通信设备,可以灵活的与外部设备进行全双工数据交换。有别与USART,还有一个UART,它在USART基础上裁剪掉了同步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是 UART因此在不考虑同步通信时,USART与UART没有太大差别
串口通信一般是以帧格式传输数据,即一帧一帧传输,每帧包含有起始信号、数据信息、停止信息,可能还有校验信息。
USART满足外部设备对工业标准 NRZ 异步串行数据格式的要求,并且使用了小数波特率发生器,可以提供多种波特率,使得它的应用更加广泛。USART 支持同步单向通信和半双工单线通信;还支持局域互连网络 LIN、智能卡(SmartCard)协议与 lrDA(红外线数据协会) SIR ENDEC规范。
USART支持使用 DMA,可实现高速数据通信。

以下时USART的框图:

STM32串口通信学习总结

注:fCK 可以是 fLSE、fHSI、fPCLK、fSYS.

 

由框图我将其分为四部分来学习:

  • 功能引脚
  • 寄存器
  • 控制器
  • 波特率生成

3.1 功能引脚

引脚

功能

TX

发送数据输出引脚。

RX

接收数据输出引脚

nRTS

请求以发送,n表示低电平有效。如果使能 RTS 流控制,当USART接收器准备好接收新数据时就会将nRTS变成低电平;当接收寄存器已满时,nRTS将被设置为高电平。该引脚只适用于硬件流控制。

nCTS

清除以发送(Clear To Send),n表示低电平有效。如果使能 CTS流控制,发送器在发送下一帧数据之前会检测 nCTS 引脚,如果为低电平,表示可以发送数据,如果为高电平则在发送完当前数据帧之后停止发送。该引脚只适用于硬件流控制

SCLK

发送器时钟输出引脚。这个引脚仅适用于同步模式。

3.2数据寄存器

USART说数据寄存器(USART_DR)只有低 9 位有效,并且第 9 位数据是否有效要取决于USART 控制寄存器 1(USART_CR1)的 M 位设置,当 M 位为 0 时表示 8 位数据字长,当 M位为 1 表示 9 位数据字长,我们一般使用 8位数据字长。
USART_DR包含了已发送的数据或者接收到的数据。USART_DR实际是包含了两个寄存器,一个专门用于发送的可写 TDR,一个专门用于接收的可读 RDR。当进行发送操作时,往 USART_DR写入数据会自动存储在 TDR内;当进行读取操作时,向 USART_DR读取数据会自动提取 RDR 数据。
TDR和RDR都是介于系统总线和移位寄存器之间。串行通信是一个位一个位传输的,发送时把 TDR 内容转移到发送移位寄存器,然后把移位寄存器数据每一位发送出去,接时把接收到的每一位顺序保存在接收移位寄存器内然后才转移到 RDR。
USART 支持 DMA 传输,可以实现高速数据传输。

3.3 控制器

USART有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等。
使用USART之前需要向USART_CR1寄存器的UE位置1使能USART,UE位用于开启供给串口的时钟。发送或者接收数据字长可选8或9位,由USARTT_CR1的M位控制。

3.3.1发送器

当USART_CR1寄存器的发送使能位TE置1时,启动数据发送,发送移位寄存器的数据会在TX引脚输出,低位在前,高位在后。如果是同步模式SCLK也输出时钟信号。
一个字符帧发送需要3部分:起始位、数据帧、停止位。起始位是一个位周期的低电平,位周期就是每一位占用的时间;数据帧就是我们要发送的7或8或9位数据,数据是最低位开始传输的;停止位是一定时间周期的高电平。
停止位的时间长短可以通过USART控制寄存器2(USART_CR2)的STOP[1:0]位控制,可选0.5个、1个、1.5个、2个停止位。默认使用1个停止位。2个停止位适用于正常USART模式、单线模式和调制解调器模式。0.5和1.5个停止位用于智能卡模式。
当发使能位TE置1之后,发送器开始会发送一个空闲帧(一个数据帧长度的高电平),接下来就可以往USART_DR寄存器写入要发送的数据。在写入最后一个数据后,需等待USART状态寄存器(USART_SR)的TC位为1,表示数据传输完成。USART_CR1寄存器的TCIE位置1,则产生中断。
发送数据时,几个重要的标志位如下:
TE:发送使能。
TXE:发送寄存器为空,发送单个字节时使用。
TC:发送完成,发送多个字节数据时候使用。
TXIE:发送完成中断使能。


3.3.2 接收器
将CR1寄存器的RE位置1,使能USART接收,使得接收器在RX线开始搜索起始位。在确定起始位后,就根据RX线电平状态把数据存放在接收移位寄存器内。接收完成后就把接收移位寄存器的数据移到PDR内,并把USART_SR寄存器的RXNE位置。如果USART_CR2寄存器的RXNEIE置1可以产生中断。
接收数据时,几个重要的标志位如下:
RE: 接收使能。
RXNE:读数据寄存器非空。
RXNEIE:发送完成中断使能。

 

3.4 波特率生产

 

接收器和发送器(Rx和Tx)的波特率设置为USARTx_BRR寄存器中编程的相同值。

公式1;适用于标准USART(包括SPI模式)的波特率(OVER8=0或1)

16倍过采样时的公式为;STM32串口通信学习总结

8倍过采样时的公式为:STM32串口通信学习总结

如何从USARTx_BRR寄存器中获取USARTDIV呢?

如本次实验的要通过获取115200波特率。

16倍过采样时:

USARTDIV=8000000/115200

BRR=USARTDIV=69d=0x45

16倍过采样时:

USARTDIV=2*8000000/115200

USARTDIV=138.89(139d=8Bh)

BRR[3:0]=Bh>>1=1h

BRR=0x8B

 

3.5 总结

UART异步通信方式特点:

  1. 全双工异步通信
  2. 小数波特率发送器系统,提供精准的波特率
  3. 可配置的16倍过采样或8倍过采样,因此为速度容差与时间容差的灵灵活配置提供了可能
  4. 可编码的数据字长度(8位或者9位)
  5. 可配置的停止位(支持1或者2位停止位)
  6. 可配置的适用DMA多缓存器通信
  7. 单独的发送器和接收器使能位
  8. 检测标志:1.接收缓存器2.发送缓冲器3.传输结束标志
  9. 多个带标志的中断源,触发中断。
  10. 其他:校验控制,四个错误检测标志

4、STM32串口通信过程

 

STM32串口通信学习总结

USAT异步通信方式引脚(STM32F767IGT6)

串口号

USART_RX

USART_TX

USART1

PA10(PB7)

PA9(PB6)

USART2

PA3(PD6)

PA2(PD5)

USART3

PB11(PC11)(PD9)

PB10(PC10)(PD8)

UART4

PA1(PC11)

PA0(PC10)

UART5

PD2

PC12

USART6

PC7(PG9)

PC6(PG14)

5、串口配置的一般步骤及代码分析

步骤

使用代码

  • 串口时钟使能

RCC_APBxPeriphClockCmd();

GPIO时钟使能

RCC_AHB1PeriphClockCmd();

  • 引脚复位映射

GPIO_PinAFConfig();

  • GPIO端口模式设置

GPIO_Init();模式设置为GPIO_MoDe_AF

  • 串口参数初始化

USART_Init();

  • 开启中断并初始化NVIC

NVIC_Init();

 

USART_ITConfig();

  • 使能串口

USART_Cmd;

  • 编写中断处理函数

USARTx_IRQHandler();

  • 串口数据收发

Void USART SentDate();//发送数据到串口

 

Uint16_t USART_ReceiveDate();//接收数据

  • 串口传输状态获取

FlagStatus USART_GetFlagStatus();

 

Void USART_ClearITPendingBit();

 

5.1代码分析

5.1.1 USART初始化结构体

初始化结构体的定义在stm32f7xx_hal_uart.h中,初始化库函数定义在stm32f7xx_hal_uart.c中。

STM32串口通信学习总结

  1. Instance:串口选择
  2. USART_BaudRate:波特率设置。标准库函数会根据设定值计算得到USARTDIV值,从而设置USART_BRR的寄存器值,我们通常设置为115200。
  3. USART_WordLength:.数据帧字长,它设定USART_CR1寄存器M位的值。如果没有使能奇偶位校验控制,一般使用8数据位。
  4. USART_StopBits停止位设置。停止位有1、1.5、2三种,通常有一个停止位
  5. USART_Parity:奇偶校验控制选择。通常选择无奇偶校验。
  6. USART_Mode:USART模式选择有USART_Mode_Rx和USART_Mode_Tx,允许使用逻辑或运算选择两个,它设定 USART_CR1寄存器的 RE 位和 TE位。所以通常设置为收发模式
  7. USART_HardwareFlowControl:硬件流控制选择,只有在硬件流控制模式下才有效,可选有,使能RTS、使能CTS、同时使能RTS和CTS、不使用硬件流。
  8. HAL_UART_Init:初始化设置并使能USART6后调用HAL_UART_MspInit()函数。
  9. HAL_USART_Receive:该函数会开启接收中断,标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量

5.1.2 UART底层初始化,时钟使能,引脚配置,中断配置

HAL_UART_MspInit()函数会被HAL_UART_Init()函数调用,在stm32f7xx_hal_uart.c中可看见一个__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)函数,weak即为弱定义,如果其他地方定义了,则执行定义的,不会出现重定义错误,如果其他地方未定义,只有这个弱定义,则执行此弱定义。

STM32串口通信学习总结

  • GPIO_InitTypeDef  GPIO_Initure:句柄定义
  • If条件语句:判断是否时串口x,此处可以将6个串口的GPIO配置都写入,自建库,以后就可直接调用
  • _HAL_RCC_GPIOC_CLK_ENABLE():使能GPIOC时钟
  • __HAL_RCC_USART6_CLK_ENABLE():使能USART6时钟
  • GPIO_Initure:GPIO初始化配置,包括工作模式、输出模式、输出速度、复用功能
  • HAL_GPIO_Init:初始化GPIO结构体
  • HAL_NVIC_EnableIRQ:使能USART6中断通道
  • HAL_NVIC_SetPriority:设置中断优先级,抢占优先级3,子优先级3

5.1.3 接收器

STM32串口通信学习总结

HAL_UART_RxCpltCallback(huart)函数在使用时,就调用HAL_UART_RxCpltCallback函数进行数据的接收。数据从串口接收端接收,并在使能情况下,自动写入接收数据寄存器。在定义中已定义USART_RX_STA标志位,bit15位为接收完成标志,即接收到0x0a,bit14位为接收到0x0d,bit13~bit0位接收到的有效字节数目,因此,本代码主要判断数据结尾是否到0x0d0a.

5.1.4中断服务程序

STM32串口通信学习总结

本中断服务程序主要处理超时处理

5.1.5 发送器

STM32串口通信学习总结

发送器位于主循环中,主要是判断已接收到标志位0x0a0d后,将接收寄存器的值赋给发送寄存器,而发送寄存器向串口发送数据。

4.1.6 实验结果

STM32串口通信学习总结

6、问题总结

6.1 调试中遇到的问题

1.无论PC发什么,stm32都没有回应?

调试过程:把初始化的程序与网上众多程序员写的初始化程序做了比较,没有发现不一样的地方。觉得可能是是程序的问题,因此dubug了一下,发现在我设置的接收数组中,是有值写入的,也就是接收寄存器能够接收到PC端发送的值,按程序的运行,接下来应该是将接收数组赋值给发送寄存器,可问题就在于发送寄存器中没有收到赋值。检查程序后发现赋值处是有问题的,于是进行修改

  1. 无论PC端发送什么都乱码?

调试过程:在确定了软件上能过接收到PC端发来的信号,并且能发送出去的前提下,

PC窗口却出现乱码现象,判断软件上是没有问题的,于是用示波器去测量硬件数据,发现PC接收端与STM32F767芯片之间的一块控压芯片存在虚焊。发现问题不要一味认为是软件问题,需要软硬件兼顾的区考虑。

3.stm32发回来的内容与PC发送的不一致?

调试过程:用示波器观测数据,发现收发的数据都是正确的,但电平宽度不一致,由此得知两者的波特率不一致,进一步计算得知是stm32的串口波特率不对,后发现程序默认时钟用的MSI内部时钟,而波特率固定的四个时钟中没有MSI,因此修改使用外部高速时钟HSE,其时钟频率为8MHz。

需说明的是,配置时钟需要了解时钟树如何区配置,建议利用STM32CubeMX来学习,如果不会编写其时钟代码,可用其生成程序。