[STM32系列]一、HAL库的串口中断接收

2023-11-18

[STM32系列]一、HAL库的串口中断任意长度接收

1、前言

HAL即硬件抽象层(英语:Hardware Abstraction Layer),实现了不同硬件的统一接口操作。这就极大的简化了程序员的移植工作,搭配STM32CubeMX,使用起来非常方便。

2、回调函数

HAL库使用了很多的回调机制,这样写能够更好的实现程序的分层处理,不影响程序的主体框架,方便后期修改移植。

3、HAL库中断接收函数使用

使用HAL_UART_Receive_IT函数前,需要使能串口的接收中断,并配置中断优先级。

 /* Peripheral clock enable */
    __HAL_RCC_USART2_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART2 GPIO Configuration    
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART2 interrupt Init */
    HAL_NVIC_SetPriority(USART2_IRQn, 1, 1);
    HAL_NVIC_EnableIRQ(USART2_IRQn);

在对应的串口中断函数中需要对应的中断处理

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}

这时就可以使用
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
函数接收了,该函数会打开接收中断接收数据,函数的第一个参数指定接收串口的结构体指针,第二个参数为接收数据指针,第三个参数为接收数据长度。该函数没有超时机制,必须要指定接收的数据长度,在数据没有达到接收长度时该函数会一直阻塞,这就要求接收的数据长度必须为已知,在接收不定长度数据时会不适用。
在使用串口接收Modbus-RTU数据时,需要接收不定长的数据帧,并且要求非阻塞接收。像在标准库中接收数据一样,这里可以通过HAL_UART_Receive_IT接收单个字节的数据,在接收回调函数中加入超时处理即可完成一帧数据的接收。接收流程如下:

Created with Raphaël 2.2.0 开始 接收一个字节 超时? 帧处理 结束 yes no

保证数据帧完整的接收,就需要在接收完一个字节数据的时候将计时清零,继续下一次接收,直到超时退出,然后再处理这一帧数据。具体实现内容如下:

//数据接收结构体
struct M_Rev{
	uint8_t revcnt;			//接收计数
	uint8_t revact;			//开始标志
	uint8_t oldcnt;			//上次计数
	uint32_t revtick;		//接收计时
	uint8_t revbuff[MODBUS_MAX_LEN];		//接收缓存
}Modbus_Rev;
//接收回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART2)		//判断串口
	{
		if(Modbus_Rev.revcnt == 0)		//帧第一个数据
		{
			if(Modbus_Rev.revact == 1)	//首次接收
			{
				Modbus_Rev.revact = 2;		
			}
			else	//非首次接收
			{
				Modbus_Rev.revbuff[0] = Modbus_Rev.revbuff[Modbus_Rev.oldcnt];	//上一次接收数据位置
			}	
			HAL_TIM_Base_Start_IT(&htim2);	//开启定时器
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);	//开启指示灯
		}		
		Modbus_Rev.revcnt += 1;	//接收计数
		if(Modbus_Rev.revcnt >= MODBUS_MAX_LEN)	Modbus_Rev.revcnt = MODBUS_MAX_LEN - 1;	
		
		Modbus_Rev.revtick = 0;	//计时清0
		HAL_UART_Receive_IT(huart, &(Modbus_Rev.revbuff[Modbus_Rev.revcnt]), 1);	//接收下一次数据
	}
}
//定时器回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	Modbus_Rev.revtick += 1;				//计时增加
	if(Modbus_Rev.revtick > MAX_TIM_CNT)	//定时器溢出
	{
		Modbus_Rev.revtick =0;				//计时清0
	}
	if(Modbus_Rev.revtick >= MODBUS_T35)	//接收超时
	{
		if(Modbus_Rev.revact == 2)			//首次接收
		{
			Modbus_Rev.revact = 0;			//关闭首次接收
		}	
		Modbus_ReciveData(Modbus_Rev.revbuff,Modbus_Rev.revcnt);		//完成一帧接收,处理
		Modbus_Rev.oldcnt = Modbus_Rev.revcnt;		//保存接受位置
		Modbus_Rev.revcnt = 0;				//接收计数清0
		HAL_TIM_Base_Stop_IT(&htim2);	//关闭定时器
		
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);	//关闭指示灯
	}
}

其中要注意的一点是,在第二帧接收时,由于接收的地址是上一帧的接收位置 + 1所以需要保存其位置,将其数值赋值到这一帧的第一个字节即可。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[STM32系列]一、HAL库的串口中断接收 的相关文章

  • c项目makefile多重定义错误

    这个问题是一个对应于创建的repexthis问题 在我的嵌入式 C 项目中 我有两个独立的板 我想为每个板创建两个 c 文件 master c 和 Slave c 其中包含自己的特定main 功能 我使用 stm32cumbemx 生成带有
  • 以字符串形式接收数字(uart)

    我正在尝试通过 uart 接收一个包装为字符串的数字 我发送数字 1000 所以我得到 4 个字节 空字符 但是 当我使用 atoi 将数组转换为数字并将整数与 1000 进行比较时 我并不总是得到正确的数字 这是我用于接收号码的中断处理函
  • 在 MCU 内部 FLASH 中从一个固件跳转到另一个固件

    我目前正在开发针对 STM32F030C8 的引导加载程序固件应用程序 我在分散文件中指定引导加载程序应用程序将占用主内存位置 0x08000000 到 0x08002FFF 扇区 0 到扇区 2 我还编写了一个主固件应用程序 存储在0x0
  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • 140-基于stm32单片机智能晾衣杆控制系统Proteus仿真+源程序

    资料编号 140 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 光敏传感器 蜂鸣器 LED灯 制作一个基于stm32单片机智能晾衣杆控制系统Proteus仿真 2 通过光敏传感器
  • 137-基于stm32单片机智能保温杯控制装置Proteus仿真+源程序

    资料编号 137 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DS18B20传感器 电机 制作一个基于stm32单片机智能保温杯控制装置Proteus仿真 2 通过DS18b20传感器检测当前保温杯水的温度 并且
  • STM32F103概要

    The STM32F103x4 STM32F103x6 STM32F103xC STM32F103xD and STM32F103xE are a drop in replacement for STM32F103x8 B medium d
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • [MM32硬件]搭建灵动微MM32G0001A6T的简易开发环境

    作为学习单片机的经典 自然是通过GPIO点亮LED 或者是响应按钮的外部中断例程 这我们看看SOP8封装的芯片MM32G0001A6T得引脚 除了VDD和GND固定外 我们可以使用PA14 PA1 PA13 PA15 PA2 PA3这六个G
  • 硬件基础-电容

    电容 本质 电容两端电压不能激变 所以可以起到稳定电压作用 充放电 电容量的大小 想使电容容量大 使用介电常数高的介质 增大极板间的面积 减小极板间的距离 品牌 国外 村田 muRata 松下 PANASONIC 三星 SAMSUNG 太诱
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • VS Code 有没有办法导入 Makefile 项目?

    正如标题所说 我可以从现有的 Makefile 自动填充 c cpp properties json 吗 Edit 对于其他尝试导入 makefile 的人 我找到了一组脚本 它们完全可以实现我想要实现的目标 即通过 VS Code 管理
  • STM32的HAL中实现单按、长按和双按功能

    我正在尝试实现单击 双击和长按功能来执行不同的功能 到目前为止 我已经理解了单击和长按的逻辑 但我不知道如何检测双击 至于代码 我使用计数器实现了单击和长按 但代码仅停留在第一个 if 条件上 bool single press false
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • STM32 上的 ADC 单次转换

    我正在研究 STM32 F103x 上的 ADC 编程 并从最简单的情况 单次转换开始 测量内部温度传感器 连接到 ADC1 的值 并使用 USART 将其发送到 COM 端口 目标似乎很明确 但是当我尝试将源代码下载到闪存时 它不会向 C
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • STM32F0、ST-link v2、OpenOCD 0.9.0:打开失败

    我在用着发射台 http www ti com ww en launchpad about htmlgcc arm none eabi 4 9 2015q2 为 STM32F0 进行编译 现在我想使用该集合中的 arm none eabi
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • 移动数组中的元素

    我需要一点帮助 我想将数组中的元素向上移动一个元素 以便新位置 1 包含位置 1 中的旧值 new 2 包含 old 1 依此类推 旧的最后一个值被丢弃 第一个位置的新值是我每秒给出的新值 我使用大小为 10 的数组 uint32 t TE

随机推荐

  • 计算机行业应届生秋招春招究竟拼的是什么?

    计算机行业是被行外人神话的行业 也是被行内人吐槽的行业 2020年中国高校IT行业毕业生达到了将近70万人 这是什么概念 这样的情况下应届生的顺利就业将会是很大的问题 也就是说几十计算机行业的人才需求很大 也将面临着很大一部分毕业生找不到工
  • iOS系统语音识别

    iOS10语音识别框架Speech 项目中用到语音识别功能 这里简单的进行了一下封装 大概实现了系统语音识别的功能 还没测试 应该会有很多坑 语音识别功能封装 系统的语音识别 外部语音输入 实现语音转文字功能 项目地址 https gith
  • Tello无人机飞控(Python)程序设计

    Tello无人机飞控 Python 程序设计总结 1 py飞控库介绍 tello的几个不同的飞控库有什么区别吗 用哪个好些 Tello的几个不同飞控库主要是针对Python开发者提供的控制无人机的工具包 它们各有特点和使用方式 以下是对一些
  • 闪回版本查询+闪回版本查询案例1+闪回版本查询案例2

    闪回版本查询 闪回版本查询提供了一个审计 检查行改变的查询功能 通过它可以查找到 所有已经提交了的行记录 语法 select column name column name from table name versions between
  • 5G智慧交通白皮书 附下载地址

    智慧交通是人民对美好生活的向往之一 智慧交通从安全 效率 节能等方面改善人民的出行体验 无人驾驶的发展和普及进一步改变人们的生活方式 智慧交通业务丰富 面对不同的应用场景 需要专属的解决方案 网络联接 实时通信是智慧交通的基础 5G 赋能智
  • 围棋:一间低夹

    一间低夹 搜索结果 哔哩哔哩 Bilibili 1 复杂的新版一间高夹 第一集 复杂的新版一间高夹 第一集 哔哩哔哩 bilibili 2 复杂的新版一间高夹 第二集 复杂的新版一间高夹 第二集 哔哩哔哩 bilibili 3 复杂的新版一
  • java的六大框架_常用的java开发框架介绍 (初学者必备的六大框架)

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 常用的java开发框架java作为主流的开发语言之一其框架的使用也是非常广泛的 java到javaee部分全部是在以框架来开发 因为框架可以大大节约时间以及成本 那么java中常用的主流框架都有
  • Freetype编译

    编译freetype步骤 1 解压包freetype 2 10 0 tar 2 cd freetype 2 10 0 3 cd builds unix 4 chmod 777 configure 创建一个文件夹 media private
  • java8特性:Stream高效操作数组集合

    简介 Stream 作为 java8 的新特性 基于 lambda 表达式 是对集合对象功能的增强 它专注于对集合对象进行各种高效 便利的聚合操作或者大批量的数据操作 提高了编程效率和代码可读性 Stream 的原理 将要处理的元素看做一种
  • 通讯录管理系统C语言链表实现

    本程序采用链表的方式可以实现对于通讯录信息的管理操作主要有增 删 改 查 显示全部信息 退出六个功能 代码注释都有逻辑简单易懂适合初学者进行链表的学习 代码如下 include
  • 全新范式

    在本文中提出了一种简单的注意力机制Box Attention 它支持网格特征之间的空间交互 从感兴趣的Box中采样 并提高了Transformer针对多个视觉任务的学习能力 具体来说 介绍的BoxeR 即Box Transformer的缩写
  • CNN:Windows下编译使用Caffe和Caffe2

    用于检测的CNN分为基于回归网络的方法和基于区域 CNN网络的方法 其中基于回归网络的方法典型为YOLO9000 可以兼容使用VGG Net框架 其中基于区域 CNN网络方法 大量使用了Caffe作为基础CNN框架 准备工作 python2
  • 安装nedo.js 'npm'不是内部或外部命令,也不是可运行的程序 或批处理文件

    npm 不是内部或外部命令 也不是可运行的程序 或批处理文件 问题 没有npm命令需要按需node js npm 不是内部或外部命令 也不是可运行的程序 或批处理文件 一 下载安装node js nodejs官网 https nodejs
  • Spring Boot Metrics使用

    Spring Boot 使用Metrics监控 导入pom依赖
  • 2021年第八届大唐杯全国大学生移动通信5G技术大赛省赛

    2021年第八届大唐杯全国大学生移动通信5G技术大赛省赛 实验背景 勘站规划 网络部署 开通调测 业务认证摘自 https www bilibili com video BV1Hr4y1Y7m8 spm id from 333 337 se
  • vue+$emit调用父级方法,添加其他参数

    前言 我们在vue中子组件调用父组件的方法使用的是this emit 方法名 参数 但是在某些特定场合 我们还希望可以在父组件那里添加其他参数 实现方法
  • 新手学习Python要注意的13个问题

    作为一门易学的编程语言 Python对初学者来说确实是一个非常好的选择 不过 初学者在学习Python的过程中可能会遇到一些常见的问题 以下是一些常见的Python学习问题 语法错误 语法错误是最常见的问题之一 初学者经常会忘记冒号 括号
  • llvm之IR设计

    llvm之IR设计 引言 1 逻辑关系 2 class Module 3 class IRBuilder 4 class Instruction 5 class Constant 6 class Function 引言 llvm IR是ll
  • v-if与v-show的区别=====》面试题

    共同点 都是控制元素显示或隐藏的指令 区别 v show 控制元素无论是true还是false都会被渲染出来 通过diaplay none控制元素隐藏 v if控制元素是true渲染 是false不渲染 在dom树结构中不显示 加分回答 应
  • [STM32系列]一、HAL库的串口中断接收

    STM32系列 一 HAL库的串口中断任意长度接收 1 前言 2 回调函数 3 HAL库中断接收函数使用 1 前言 HAL即硬件抽象层 英语 Hardware Abstraction Layer 实现了不同硬件的统一接口操作 这就极大的简化