欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

STM32基础教程(CubeMX)串口通信(USART协议)

程序员文章站 2022-04-17 09:00:27
串口通信原理串口通信   通过单一数据线进行数据传输的通信方式,另外还有并行通信的方式。串口通信一次只能发送一个字符,包括起始位、数据位、校验位和停止位。单工、半双工、全双工、异步、同步单工:数据只能单向传输。半双工:数据可以双向传输,但是不能同时发送。全双工:数据可以双向传输,且可以同时发送。异步(Universal):通信双方的时钟不一样时的通信。同步(Synchronous):通信双方的时钟一样时的通信。UART和USARTUART(通用异步收发器)和USART(通用同步异步...

串口通信原理

串口通信

通过单一数据线进行数据传输的通信方式,另外还有并行通信的方式。串口通信一次只能发送一个字符,包括起始位、数据位、校验位和停止位。

单工、半双工、全双工、异步、同步
  • 单工:数据只能单向传输。
  • 半双工:数据可以双向传输,但是不能同时发送。
  • 全双工:数据可以双向传输,且可以同时发送。
  • 异步(Universal):通信双方的时钟不一样时的通信。
  • 同步(Synchronous):通信双方的时钟一样时的通信。
UART和USART
  • UART(通用异步收发器)和USART(通用同步异步收发器):串口通信的一种通信协议。速率不快,可全双工,结构上一般由波特率发生器、UART/USART发送器、UART/USART接收器组成,硬件上只有两条线,一收一发。
  • 通信格式:通信时,高电平表示没有数据传输,高电平后的第一个低电平表示数据传输开始,之后接受数据,接受完毕后拉到高电平,最少需要一个高电平的停止位。即,传送一个字节,至少需要10位的空间。通信的两个芯片必须共地,两个芯片的输出TXD和输入RXD分别连接(A的输入连接B的输出),且STM32的TXD设置为输出推挽模式,RXD设置为输入上拉模式。通信频率就是波特率,即一个信号保持的时间是波特率的导数。
  • 与电脑的通信:UART通信方式电脑不具备,电脑的通信方式是USB通信,它比UART复杂得多。为了实现串口与电脑的通信,需要通过一个转换芯片来进行协议的转换,并且在电脑端还需要软件来显示串口发送来的内容,这个软件就是“串口调试助手”。

CubeMX的操作

USART的设置
  1. 在"Pinout & Configuration"界面下,左侧选择下拉菜单"Connectivity",下拉菜单中选择USART,你会发现有好几个可以选择,具体使用哪个,需要参考原理图,看USB转串口连接的是哪个,这里选择USART1。
  2. 中间的界面里出现对应的窗口,“Mode”下“Mode”选择异步通信(asynchronous)。
  3. “Mode”下方的“Configuration”中,选择"Parameter Settings"窗口。第一个下拉菜单第一个波特率一般选择115200就可以了,第二个数据位选8位,第三个奇偶校验选择无(),第四个停止位一般选1位(设置成2位更可靠)。
  4. “Mode”下方的“Configuration”中,选择"NVIC Settings"窗口,勾选串口中断。原则:一个中断服务一个外设,不同中断使用相同变量保证他们的优先级一致。防止出现未知错误(打断造成的错误)。
  5. 设置作为串口通信的串口的状态,即输入(Rx)设置为上拉电阻,输出(Tx)设置为推挽模式(Altermate Function Push Pull)。输入上拉是因为USART协议中,高电平表示没有信号传入。

Keil5的操作

阻塞式发送数据
  • 不带中断的发送:使用函数HAL_UART_Transmit(UART的地址,发送的数组的地址,发送的数组的大小,发送的时间)。其中“发送的数组的大小”是指发送的字节数,不包括空字符;“发送的时间”参数限制了发送的总时间,如果发送的总时间超过这个事件就不发送了。
  • 重定向Printf函数:stdio.h头文件中声明了一个fputc函数,使用printf发送字符串时,相当于多次调用这个函数,所以,只要在自己的任意一个c文件中定义这个函数并编辑,把传入它的这个字符输出到自己想要的地方即可完成对Printf的重定向,传入它的文件指针不管,就可以在其他地方如常使用Printf了。
自己重新编写的fputc函数示例(发送到USART1)
 /**
  * @brief 对Printf进行重定向的函数,发送到USART1,不带中断
  * @param ch是printf函数需要发送的一个字符;file是目标文件,这里没有使用这个参数
  * @retval 未知
  */ int fputc(int ch, FILE * file) { HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,50); return 0; } 
阻塞式接收数据
  • 利用中断接收:定义一个全局变量字符数组,在主函数中调用带中断的接收函数HAL_UART_Receive_IT(USART通道地址,接受的数据存放的数组地址,接受的数据大小)。之后再中断回调函数HAL_UART_RxCpltCallback中对接收到的数据进行处理,并且再使用一次带终端的接收函数开始下一次的数据接收。

例程,该程序还将历史接收数据存储了起来:
主函数文件中定义全局变量:uint16_t Key_Detection(GPIO_TypeDef * Key_Port, uint16_t Key_Pin, GPIO_PinState Level);
主函数中调用带中断的数据接收函数HAL_UART_Receive_IT(&huart1,USART_Receive,1);
中断回调函数所在文件需加头文件:#include "stdio.h" #include "lcd.h" #include "math.h" #include "string.h"
中断回调函数:

extern uint8_t USART_Receive[5], USART_Receive_Save[200],USART_Receive_Number; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { char str[100] = {0}; if(huart == &huart1) { /*将接收到的数据显示在LCD上*/ strcat(str,"I have received:"); strcat(str,(char *)USART_Receive); LCD_ShowString(5,305,200,5,12,(uint8_t *)str); /*将接收到的数据存储在Save数组中,并且开始接受下一个字节*/ USART_Receive_Save[USART_Receive_Number] = USART_Receive[0]; USART_Receive_Number++; HAL_UART_Receive_IT(&huart1,USART_Receive,1); } 
使用DMA进行通信

原理:DMA是一个寄存器,完成搬运数据的任务。在完成任务后会通知CPU完成,如果有设置中断就进入相应的中断,期间CPU不被占用。

  1. 配置好串烤的相关参数
  2. 配置DMA,配置的地方就在设置USART的地方,在下方的窗口里面找到DMA的界面,选择添加一个DMA,配置一般选择默认就可以了。DMA的模式分为普通模式和循环模式,循环模式就是把要求发送的数据重复发送,直到接收到停止指令。
  3. DMA无法使用printf发送,它的发送函数为HAL_UART_Transmit_DMA(UART地址,发送的数组,发送的字节数),发送的字节数不知道时,可以使用"string.h"里面的strlen(字符串);。它的接收函数为HAL_UART_Receive_DMA(UART地址,接收的数组,接收的字节数)
DMA不定长接收

原理:就是说,未知数据长度大小,当不发送数据一定时间的时候就认为数据已经结束了。串口闲置中断就是,当接收了数据之后,串口闲置了一个字节的长度之后就会触发串口闲置中断。

本文地址:https://blog.csdn.net/weixin_43718316/article/details/107988929

相关标签: STM32 单片机