STM32-CubeIDE用串口通讯

ops/2024/10/17 21:26:57/

USART串口通讯

一、轮询模式

1.设置所接引脚为UART异步模式

在这里插入图片描述在这里插入图片描述

  • 选择完成CTRL+S保存。

2.编写测试代码(自动发送hello world)

  • 在mian函数里面编写代码
    在这里插入图片描述
  • 原函数
    在这里插入图片描述
  • 调用函数,需要数据类型一致,使用函数通过串口发送数组里面的数据
    在这里插入图片描述
  • 打开串口助手测试
  • 选择对应的端口,波特率需要一致。
    在这里插入图片描述

3.编写接收数据的代码

在这里插入图片描述

  • 通过串口助手测试代码正常使用。
    在这里插入图片描述

二、中断模式收发

1.打开URAT的中断功能,然后保存自动生成代码

在这里插入图片描述

2.使用中断发送数据

在这里插入图片描述

3.使用中断接收数据

  • 串口使用中断模式来接收信息,没有等待时间,如果程序写在while循环中,会有这次数据还没有接收完成就去接收下次数据的情况,所以需要将对应程序写在中断函数的回调函数中。
  • stm32f1xx_hal_uart.c文件中,有一个回调函数,我们可以重新定义其内容
    在这里插入图片描述
  1. 将定义的数组改成全局变量
/* USER CODE BEGIN PV */
uint8_t receiveData[2];
/* USER CODE END PV */
  1. 复制回调函数到main.c文件中,重新定义回调函数
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {HAL_UART_Transmit_IT(&huart1, receiveData, 2);GPIO_PinState state = GPIO_PIN_SET;	if (receiveData[1] == '1') {state = GPIO_PIN_RESET;if (receiveData[0] == 'L') {HAL_GPIO_WritePin(GPIOB, LED_MCU_Pin, state);}}if (receiveData[1] == '0') {state = GPIO_PIN_SET;if (receiveData[0] == 'L') {HAL_GPIO_WritePin(GPIOB, LED_MCU_Pin, state);}}HAL_UART_Receive_IT(&huart1, receiveData, 2);				//每次执行完回调函数内容后,要继续为下次接收开启串口接收数据
}
/* USER CODE END 0 */

3.串口使用DMA模式接收发送数据

  • 无论用上面哪种方式,询问或者中断,都会占用CPU,所以可以使用DMA来搬运数据,等搬运完成触发中断就可以去处理。减少了对CPU的占用率。
  1. 开启DMA功能。
    在这里插入图片描述
  2. 将串口中断函数改成DMA函数,修改其后缀即可,其他不变。
    在这里插入图片描述
    在这里插入图片描述
  3. 下载调试发现程序正常,正常接收发送数据。

4.串口接收不定长数据

  • 我们可以认为空闲(ldle)中断发生时,就是一帧数据包接收完成了,此时再对数据进行分析处理即可。
  HAL_UARTEx_ReceiveToIdle_DMA(&huart1, receiveData, sizeof(receiveData));/* 接收空闲中断,接收长度是最大长度。而不是接收数据的长度。可以设置为数组的长度。而数组的长度要尽量大。不至于溢出 */
  • HAL_UARTEx_ReceiveToIdle_DMA对应的回调函数不是之前RxCpltCallback回调函数了,而是RxEventCallback这个回调函数了。
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {if (huart == &huart1) {									//判断触发的中断是哪个中断HAL_UART_Transmit_DMA(huart, receiveData, Size);	//将接收的数据发送回去HAL_UARTEx_ReceiveToIdle_DMA(&huart1, receiveData, sizeof(receiveData));		//重新启动接收函数}
}
  • 下载代码,连接电脑发送数据,单片机可以正常接收到数据并且执行RxEventCallback()函数,而不是执行RxCpltCallback()这个回调函数。
  • 上面虽然实现了功能,但是当接收数据达到接收数组的一半时,也会有产生中断,使得一半之后的数据接收不到,所以需要在接收数据之后将接收过半中断给关闭了
  HAL_UARTEx_ReceiveToIdle_DMA(&huart1, receiveData, sizeof(receiveData));/* 接收空闲中断,接收长度是最大长度。而不是接收数据的长度。可以设置为数组的长度。而数组的长度要尽量大。不至于溢出 */__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);

http://www.ppmy.cn/ops/124771.html

相关文章

【数据结构】邻接表

一、概念 邻接表是一个顺序存储与链式存储相结合的数据结构,用于描述一个图中所有节点之间的关系。 若是一个稠密图,我们可以选择使用邻接矩阵;但当图较稀疏时,邻接矩阵就显得比较浪费空间了,此时我们就可以换成邻接…

Python——Matplotlib生成的图像中没有显示文字(如标签、标题和图例)

如果在Matplotlib生成的图像中没有显示文字(如标签、标题和图例),这通常是由于以系统中缺少Matplotlib默认的字体,或者字体文件无法被正确加载,那么文本可能无法渲染。 1、首先导入所需的Matplotlib库(这个…

GAN(Generative Adversarial Nets)

GAN(Generative Adversarial Nets) 引言 GAN由Ian J. Goodfellow等人提出,是Ian J. Goodfellow的代表作之一,他还出版了大家耳熟能详的花书(Deep Learning深度学习),GAN主要的思想是同时训练两个模型,生成…

JAVA基础

1.数据类型 变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。 1.1 基本数据类型 Java语言提供了八种基本类型。六种数字类型…

封装代码片段语法 vue2语法

关于函数导入 1.在untils写一个pdfService.js 关于pdf预览和下载的方法 export const previewPdf async (record) > {const pdfUrln record.url; // 直接使用 PDF 文件的 URL// const pdfUrln indexConfig.VITE_GLOB_VIEW_URL static/pdf/web/viewer.html?file reco…

使用频率最高的 opencv 基础绘图操作 - python 实现

以下是 opencv-python 基本操作绘制示例,绘制: 1)圆,2)矩形,3)线段,4)文本。 安装 opencv-python pip install opencv-python 在图上绘制圆的操作,示例如…

C语言题目练习2

前面我们知道了单链表的结构及其一些数据操作,今天我们来看看有关于单链表的题目~ 移除链表元素 移除链表元素: https://leetcode.cn/problems/remove-linked-list-elements/description/ 这个题目要求我们删除链表中是指定数据的结点,最终返…

第十五届蓝桥杯C/C++学B组(解)

1.握手问题 解题思路一 数学方法 50个人互相握手 (491)*49/2 ,减去7个人没有互相握手(61)*6/2 答案:1024 解题思路二 package 十五届;public class Min {public static void main(String[] args) {i…