薪火培训电控第四讲——通用异步收发传输器 UART

@


前言

本例程采用的是CubeMax配置基层寄存器,使用HAL库编写相关代码,基于STM32F103C6T6芯片。
CubeMax是一款对新手非常友好的通过可视图形化界面配置USART,TIM,CAN,ADC等设置的软件,HAL库也是一个封装很好的函数库,里面的函数名较为面向对象,对于初学者来说相对更简单易上手。


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是UART?

在说明UART之前,先谈谈通讯的两种类型:串行通讯和并行通信。

并行通信:将数据的各位用多条数据线同时进行传送,外加地址线和通信控制线。优点是传输速率高,缺点是长距离传输成本高,可靠性差,只适用于近距离传输。并口一次通过8根线或16根线传输数据。常见并口如HDMI。

串行通信:将数据逐位按顺序在一条传输线上传送。优点是传输线少,长距离传送时成本低,缺点是传输速率低。比如将要介绍的UART。

UART,即通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),是一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收。在UART上追加同步方式的序列信号变换电路的产品,被称为USART(Universal Synchronous Asynchronous Receiver Transmitter)。

二、UART的使用

1、UART的通信原理

UART的数据结构分为起始位、数据位、奇偶校验位、停止位、空闲位,此外还有一个重要的参数——波特率。接下来将一个个介绍它们的含义。

  • 起始位:位于整个数据的做前端,发出的一个逻辑”0”的信号,表示传输字符的开始。
  • 数据位:紧接着起始位之后。资料位的个数可以是4、5、6、7、8等,构成一个字符。通常采用ASCII码。从最低位开始传送,靠时钟定位。
  • 奇偶校验位:数据位加上这一位后,使得数据中“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验资料传送的正确性。该位数据也可以不添加。
  • 停止位:它是一个字符数据的结束标志,位于数据的末尾。可以是1位、1.5位、2位的高电平。 由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
  • 空闲位:位于传送的数据之外,为处于逻辑“1”状态,表示当前线路上没有数据传送。
  • 波特率:是衡量数据传送速率的指标。表示每秒钟传送的符号数(symbol)。一个符号代表的信息量(比特数)与符号的阶数有关。例如传输使用256阶符号,每8bit代表一个符号,数据传送速率为120字符/秒,则波特率就是120baud,而比特率是120*8=960bit/s。这两者的概念很容易搞错。

使用UART连接通信的两个设备的以上因素必须完全一致才能实现设备之间的数据通信。以下是UART工作时发送方与接收方的状态。

发送方:传送时先输出起始位“0”作为联络信号,接着为数据位、奇偶校验位和停止位。字符之间允许有不定长度的空闲位。

接收方:接收方是依靠字符帧格式来判断发送方是何时开始发送,何时结束发送的。传送开始后,不断检测传输线的电平状态,当收到一系列的“1”(空闲位或停止位)之后,检测到一个“0”,说明起始位出现,就开始接收所规定的数据位和奇偶校验位以及停止位。

当已经读了一帧数据后并且高电平持续时间 >(发送时一个高低电平的持续时间 * 停止位) :认为传输停止。
如果这时UART 的中断处于使能状态,则会进入中断函数。

2、使用CubeMax配置

  1. 新建工程,选择芯片的型号
    在这里插入图片描述在这里插入图片描述
  2. 配置时钟,Debug接口
    在这里插入图片描述在这里插入图片描述时钟树配置如下:
    在这里插入图片描述
  3. 配置USART
    在这里插入图片描述这里配置的USART1对应的引脚TX对应PA9,RX对应PA10,注意接线时设配间的TX、RX反向链接。
  4. 生成工程文件
    在这里插入图片描述

3、编写代码

在main.c中写下对应函数,以及相应参数实现数据的传输与接收

	HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)//UART接收函数
	HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)//UART传输函数

三、UART接收的三种方式

UART接收有轮询接收,中断接收和DMA接收三种方式,接下来将一个个介绍其特点作用。

1、轮询接收

轮询,顾名思义,就是一条指令一条指令的执行,只有当一条指令执行完成之后才会执行下一条指令,相比于其它的接收方式效率低下,不灵活,容易引起阻塞,即在执行一条命令时会拒绝执行突如其来的紧急命令。

2、中断接收

中断接收相比于轮询更为灵活,当更紧急的时间来临时,它会优先执行更紧急的事件即进入中断状态,把手上正在执行的事件先放在一旁。
要使用UART的中断接收,要在CubeMax的NVIC settings中使能UART中断,编写代码时也与轮询不同。首先需要在代码中调用函数
__HAL_UART_ENABLE_IT(__HANDLE__, 中断类型)
使能你所用到的中断类型,常见的中断类型有:

UART_IT_TXE      传输中断
UART_IT_RXNE     接收中断
UART_IT_IDLE     空闲接收中断

使用到的接收与发送函数为:

	HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
	HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

当中断发生时,会进入到UART的中断处理函数

void USARTx_IRQHandler(void) x取决于你使用的USART的编号,其位于stm32f1xx_it.c文件中

下面有一些常用的HAL库自带的函数名可供使用者改写的函数(可以直接调用,不用声明,但函数功能需要自己编写):

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);//传输完成进入中断
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);//传输完成部分进入中断
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);//接收完成进入中断
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//接收完成部分进入中断

3、DMA接收

这里可以做一个比喻:
轮询接收类似于你(CPU)在记录作业,老师(外部设备)在布置作业,老师说一个字你就记录一个字,但它有一个明显的缺点,如果老师在布置作业的时候你在忙于排位,你可能就会漏掉老师说的一些重要点,这时我们需要中断接收。
所谓中断接收就是当听到老师布置作业时就停止玩手机去记录作业,但它也有一个坏处,就是打排位时频繁挂机掉线是会被队友骂的。
如何解决呢?这时你需要一个好朋友(DMA)帮你记录作业,这就是DMA接收。
那究竟什么是DMA?

DMA即Direct Memory Access,译为直接存储器访问,它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。否则,CPU 需要从来源把每一片段的资料复制到暂存器,然后把它们再次写回到新的地方。在这个时间中,CPU 对于其他的工作来说就无法使用。

在配置CubeMax时需要选择DMA的通道
在这里插入图片描述
编写代码时同样需要使能中断,但是HAL库并没有封装相应的DMA中断回调函数,这时就需要我们自己写一个中断回调函数,例如:

void USER_UART_DMACallback(UART_HandleTypeDef *huart)
{
	if(huart == &huart1)
	{
		if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET)) 
	 {
		__HAL_UART_CLEAR_IDLEFLAG(&huart1);
        __HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_FE);//清除中断标志
		HAL_UART_DMAStop(&huart1);//停止DMA接收
		The_Handle_of_YourData();//对接收数据的处理
		HAL_UART_Receive_DMA(&huart1,rxdata,8);//重新使能DMA接收
	}
	}
}

希望以上内容对你有所帮助,谢谢观看!

posted @ 2021-10-30 18:15  北京理工大学机器人队  阅读(203)  评论(0编辑  收藏  举报