STM32 HAL库 UART 串口读写功能笔记
https://www.cnblogs.com/Mysterious/p/4804188.html
STM32L0 HAL库 UART 串口读写功能
串口发送功能:
uint8_t TxData[10]= "01234abcde"; HAL_UART_Transmit(&huart2,TxData,10,0xffff);//把TxData的内容通过uart2发送出去,长度是10,timeout的时间是最大值0xffff
串口接收功能1:
uint8_t value='F'; HAL_UART_Receive(&huart2,(uint8_t *)&value,1,1000);//在这个语句停留1000ms内等待接收1个字节数据,把数据存放在value中
串口接收功能2:
HAL_UART_Receive_IT(&huart2,(uint8_t *)&value,1);//程序不会在这个语句停留,直接会按照中断方式把接收数据存放在value中,但是这个语句只能使能一次串口中断。所以要在中断服务函数或者回调函数中重新使能
串口接收功能3:
if(HAL_UART_Receive_IT(&huart2,(uint8_t *)&value,1) != HAL_OK){ //这一句写在main函数的while(1)上面。用于启动程序启动一次中断接收HAL_UART_Transmit(&huart2, (uint8_t *)&"ERROR\r\n",7,10); while(1); }
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) {HAL_UART_Transmit(&huart2, (uint8_t *)&"\r\ninto HAL_UART_RxCpltCallback\r\n",32,0xffff); //验证进入这个函数了HAL_UART_Transmit(&huart2,(uint8_t *)&value,1,0xffff); //把接收到的数据通过串口发送出去 HAL_UART_Receive_IT(&huart2,(uint8_t *)&value,1); //重新打开串口中断 }
串口DMA发送
DMA的TX要这样设置
uint8_t txData[] = {"HelloWorld\r\n"};HAL_UART_Transmit_DMA(&huart2,txData,sizeof(txData));//可以通过DMA把数据发出去
DMA接收
if(HAL_UART_Receive_DMA(&huart2, (uint8_t *)rxData, sizeof(rxData)-1) != HAL_OK)//main函数while(1)前,启动一次DMA接收{Error_Handler();}
串口回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle){uint8_t temp[] = {"\r\nin Callback\r\n"};HAL_UART_Transmit_DMA(&huart2,temp,sizeof(temp)-1);//可以通过DMA把数据发出去HAL_UART_Receive_DMA(&huart2, (uint8_t *)rxData, sizeof(rxData)-1); //重新使能接收 }
main函数while(1)中不断输出rxData值
HAL_UART_Transmit_DMA(&huart2,rxData,sizeof(rxData)-1);//可以通过DMA把数据发出去
https://www.cnblogs.com/UnfriendlyARM/p/10321838.html
STM32串口接收中断——基于HAL库
写在前面
1.UART相关的头文件引用错误
由于本人直接使用MDK进行开发,没有使用CubeMX,所以一些初始化需要手动进行。在引用UART相关的头文件时,记得将"stm32l4xx_hal_conf.h"文件中的相关宏定义取消注释,如下图:
2.如何接收字符串(多次进入中断)
接收字符串主要有两种方法,一种是对中断函数进行改造,另一种是对接收回调函数进行改造。
在阐述这两种方法之前,需要介绍函数“HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)”。该函数的作用是用户自定义一个缓冲区(即参数pData),接受一定数量(由参数Size决定)的字符存入缓冲区中。同时,参数Size还决定着进入回调函数的频率,即每接收Size个字符,就进入一次回调函数。需要注意的是,Size只决定进入回调函数的频率,而不能影响进入接收中断的频率,无论Size是多少,每接收完成一个字符都会进入一次接收中断。
方法1:改造回调函数
①首先在主函数中进入主循环前的位置调用一次 HAL_UART_Receive_IT函数,定义一个字符数组getBuffer[]作为缓冲区,参数Size设定为10。即每接收10个字符,就进入一次回调函数。
②注册中断函数
1 void USART1_IRQHandler(void) 2 { 3 HAL_UART_IRQHandler(&UartHandle); //该函数会清空中断标志,取消中断使能,并间接调用回调函数 4 }
③在文件“stm32l4xx_hal_uart.h”中,我们可以看到串口接收回调函数的定义。使用“_weak”关键字定义的函数,其具有如下特性: 一般情况下和一般函数相同。但是当有一个同名函数但是不带__weak被定义时,所有对这个函数的调用都是指向后者(不带__weak那个)。也就是说,ST官方提供的这个回调函数需要我们自己进行改写。
1 /**2 * @brief Rx Transfer completed callback.3 * @param huart UART handle.4 * @retval None5 */6 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)7 {8 /* Prevent unused argument(s) compilation warning */9 UNUSED(huart); 10 11 /* NOTE : This function should not be modified, when the callback is needed, 12 the HAL_UART_RxCpltCallback can be implemented in the user file. 13 */ 14 }
我们在主函数所在的文件中对回调函数进行改写:
1 uint8_t myBuffer[] = "I have gotten your message: "; //用户提示信息 2 uint8_t Enter[] = "\r\n"; //回车换行 3 uint8_t getBuffer[100]; //用户自定义的缓冲区 4 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) 5 { 6 while(HAL_UART_Transmit(UartHandle, (uint8_t*)myBuffer, COUNTOF(myBuffer), 5000)!= HAL_OK); //发送字符串,用户提示信息 7 while(HAL_UART_Transmit(UartHandle, (uint8_t*)getBuffer, 10, 5000)!= HAL_OK); //发送用户自定义缓冲区中的数据 8 while(HAL_UART_Transmit(UartHandle, (uint8_t*)Enter, COUNTOF(Enter), 5000)!= HAL_OK); //发送回车换行 9 }
以上代码的作用是把用户发送给单片机数据再返回给用户。运行效果如下图:
我们可以看到,用户向单片机发送了10个字符,单片机向串口助手返回了这10个数据。但是以上程序只能实现一次,当我们再次向单片机发送数据时,单片机却不再返回数据。这是因为我们在中断函数中取消了中断使能,所以导致了进入一次中断后,中断被关闭,无法再次进入中断的现象。为了实现多次数据返回,我们要在中断处理函数中添加一行代码:
1 void USART1_IRQHandler(void) 2 { 3 HAL_UART_IRQHandler(&UartHandle); //该函数会清空中断标志,取消中断使能,并间接调用回调函数 4 HAL_UART_Receive_IT(&UartHandle, (uint8_t *)&value,1); //添加的一行代码 5 }
这样就可以实现多次数据返回了,新的执行结果如下图:
可见,函数HAL_UART_Receive_IT还有中断使能的作用。这一功能的实现我们可以在HAL_UART_Receive_IT函数中找到。
方法2:改造中断处理函数
①首先在主函数中进入主循环前的位置调用一次 HAL_UART_Receive_IT函数,定义一个字符value作为缓冲区,参数Size设定为1。即每接收1个字符,就进入一次回调函数。使得进入回调函数的频率与进入中断处理函数的频率相同。这样,我们就可以直接在中断函数中对接收的数据进行处理了。
②注册中断函数
1 uint8_t myBuffer[] = "I have gotten your message: ";2 uint8_t getBuffer[10];3 uint8_t Enter[] = "\r\n";4 void USARTx_IRQHandler(void)5 {6 HAL_UART_IRQHandler(&UartHandle); //该函数会清空中断标志,取消中断使能,并间接调用回调函数7 8 getBuffer[countOfGetBuffer++] = value; 9 if(countOfGetBuffer == 10) 10 { 11 while(HAL_UART_Transmit(&UartHandle, (uint8_t*)myBuffer, COUNTOF(myBuffer), 5000)!= HAL_OK); 12 while(HAL_UART_Transmit(&UartHandle, (uint8_t*)getBuffer, countOfGetBuffer, 5000)!= HAL_OK); 13 while(HAL_UART_Transmit(&UartHandle, (uint8_t*)Enter, COUNTOF(Enter), 5000)!= HAL_OK); 14 countOfGetBuffer = 0; 15 } 16 HAL_UART_Receive_IT(&UartHandle, (uint8_t *)&value,1); //由于接收中断是每接收一个字符便进入一次,所以这一行代码必须添加,否则只能接收一个字符,而无法接收整个字符串 17 }
以上代码的作用是接收每个来自用户的字符,并依次存入用户自定义的缓冲区中,数量达到10个后,将缓冲区中的所有数据返回给用户,同时清空计数,准备接下来10个字符的接收。运行效果如下图:
写在最后
看完本文,大家可能对回调函数和中断处理函数的关系产生了疑问。其实是这样的,单片机每完成接收一个字符,就会进入一次中断处理函数,而在中断处理函数中,我们又调用了函数“void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)”,该函数会间接调用回调函数,也就是说回调函数是由中断处理函数间接调用的。而函数“HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)”决定了中断处理函数调用回调函数的频率,若Size为1,则每进入一次中断处理函数都会调用一次回调函数;若Size为10,则每第十次进入中断处理函数时,才会调用回调函数。方法2使用了标准库中断处理数据的思想。
转载于:https://www.cnblogs.com/CodeWorkerLiMing/p/11487378.html
STM32 HAL库 UART 串口读写功能笔记相关推荐
- STM32cube HAL库 UART串口中断方式收发任意长度 调试笔记
STM32Cube对于新项目的开发能节省不少时间,从繁琐芯片初始化中解脱出来 1.STM32 UART初始化部分,配置好工程,采用STM32cube生成代码,初始化即已经完成. 2.串口中断方式的发动 ...
- STM32学习笔记-SMT32使用HAL库UART中断方式使用
目录 1.引言 2.配置 3.流程 1.引言 近来需要使用蓝牙模块,再了解到蓝牙模块等无线模块许多使用串口透传,便决定在研究一下串口UART 的使用方法. 由于用的板子种类每次都不一样,有F103 有 ...
- 基于STM32 HAL库的遥控小车
目录 前言 一.材料清单 二.系统概述 三.硬件设计 1.HC-SR04超声波模块 2.HC-05/06蓝牙模块 3.L298n电机驱动模块 四.代码 1.引脚设置 2.遥控部分 3.超声波报警部分 ...
- STM32 HAL库+ESP8266+华为云物联网平台
文章内容: STM32 HAL库通过串口发送AT指令完成与ESP8266的控制实现接入华为云物联网平台,并完成基本通信与控制,包括设备属性上报和命令下发解析与响应. 文末获取"STM32 H ...
- STM32 HAL库开发学习笔记: USART1串口通讯(中断方式) IDE-STM32CubeIDE
STM32串口通讯有三种方式,分别为阻塞(轮询).中断.DMA.这里将用中断的方式开发. 笔者也是刚入门STM32 HAL库开发,该笔记致希望于能帮到初学者,文中配置步骤.代码.实验现象均是笔者实践可 ...
- STM32 HAL库学习笔记1-HAL库简介
STM32 HAL库学习笔记1-HAL库简介 HAL库 SPL 库 和 HAL 库两者相互独立,互不兼容.几种库的比较如下 目前几种库对不同芯片的支持情况如下 ST 中文官网上有一篇<关于ST库 ...
- STM32 HAL库 CubeMX教程(五)串口通信基础
STM32 HAL库 CubeMX教程(五)串口通信基础 串口通信简介 CubeMX配置 初始化程序分析 程序编写 参考文献 STM32 HAL库 CubeMX系列教程 目录 串口通信简介 UART: ...
- STM32 HAL库学习笔记2 HAL库介绍
STM32 HAL库学习笔记2 HAL库介绍 CMSIS标准 一.再次认识HAL库 HAL库设计思想 HAL库实现方式 以GPIO模块为例 GPIO外设数据类型 GPIO外设接口函数 二.使用HAL库 ...
- STM32 HAL库串口收发数据
STM32 HAL库串口收发数据 许多传感器的使用方法是:单片机给传感器发送一帧数据,然后传感器返回单片机一帧有用数据,所以串口的收发功能十分重要. STM32cubeMX的配置 时钟和下载方式就不讲 ...
最新文章
- Linux12-bash变量和逻辑运行
- 辞职后五险一金的处理方式
- java mysql安装教_大学java教案之MySQL安装图解
- [BZOJ 2839]集合计数
- 还在用 Python 2.x?Python 3.7.0 正式发布!
- redis配置文件的介绍
- ROS 教程之 navigation : 用 move_base 控制自己的机器人(1)
- mysql用shell建100多字段表并导入
- php如何防止重复提交表单,如何防止php重复提交表单方法
- 聚类算法实践——层次、K-means聚类
- 吴恩达机器学习笔记七_应用机器学习的建议
- matlab阅读怎么放大镜,matlab局部放大
- PCD文件的rgb格式
- 未来客服会被人工智能代替吗?
- ES6中的Symbol类型
- Introduction to modern cryptography 第二章阅读笔记
- 安防系统的定义及相关组成部分详解
- 在Anaconda中使用jupyter的保姆级安装教程
- 无线通信学习笔记(一)
- 【Pytorch深度学习实践】B站up刘二大人课程笔记——目录与索引(已完结)