正点原子F4HAL库串口中断再解读

news2024/9/22 15:48:17

七步走,参考usart.c文件

void HAL_UART_MspInit(UART_HandleTypeDef *huart) 这个函数进行了(1)、(2)、(3)、(5)中的使能中断

void uart_init(u32 bound)函数进行了(4)、(5)、(6)

void USART1_IRQHandler(void)  中断服务函数和voidHAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)回调函数进行了最后一步(7)

具体来说

(1)串口时钟使能,GPIO 时钟使能。

		__HAL_RCC_GPIOA_CLK_ENABLE();			//使能GPIOA时钟
		__HAL_RCC_USART1_CLK_ENABLE();			//使能USART1时钟

(2)设置引脚复用器映射:调用 GPIO_PinAFConfig 函数。

	GPIO_Initure.Alternate=GPIO_AF7_USART1;	//复用为USART1

(3)GPIO 初始化设置:要设置模式为复用功能。

		GPIO_Initure.Pin=GPIO_PIN_9;			//PA9
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
		GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
		GPIO_Initure.Speed=GPIO_SPEED_FAST;		//高速
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA9

		GPIO_Initure.Pin=GPIO_PIN_10;			//PA10
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA10

(4)串口参数初始化:设置波特率,字长,奇偶校验等参数。

    UART1_Handler.Instance=USART1;					    //USART1
	UART1_Handler.Init.BaudRate=bound;				    //波特率
	UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
	UART1_Handler.Init.StopBits=UART_STOPBITS_1;	    //一个停止位
	UART1_Handler.Init.Parity=UART_PARITY_NONE;		    //无奇偶校验位
	UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
	UART1_Handler.Init.Mode=UART_MODE_TX_RX;		    //收发模式

(5)开启中断并且初始化 NVIC,使能中断(如果需要开启中断才需要这个步骤)。

		HAL_NVIC_EnableIRQ(USART1_IRQn);				//使能USART1中断通道
		HAL_NVIC_SetPriority(USART1_IRQn,3,3);			//抢占优先级3,子优先级3

        
        //该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
        HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);
      

(6)使能串口。

	HAL_UART_Init(&UART1_Handler);					    //HAL_UART_Init()会使能UART1

(7)编写中断处理函数:函数名格式为 USARTxIRQHandler(x 对应串口号)。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)//如果是串口1
	{
		if((USART_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
			}
			else //还没收到0X0D
			{	
				if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;//限制存储位置在接收缓冲区的长度范围内,USART_RX_STA的前14位(13bit之前)
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}

	}
}
 
//串口1中断服务程序
void USART1_IRQHandler(void)                	
{ 
	u32 timeout=0;
#if SYSTEM_SUPPORT_OS	 	//使用OS
	OSIntEnter();    
#endif
	
	HAL_UART_IRQHandler(&UART1_Handler);	//调用HAL库中断处理公用函数
	
	timeout=0;
    while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)//等待就绪
	{
	 timeout++;超时处理
     if(timeout>HAL_MAX_DELAY) break;		
	
	}
     
	timeout=0;
	while(HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1
	{
	 timeout++; //超时处理
	 if(timeout>HAL_MAX_DELAY) break;	
	}
#if SYSTEM_SUPPORT_OS	 	//使用OS
	OSIntExit();  											 
#endif
} 
#endif	

第七步的逻辑比较复杂,可以通过这个框图来帮助理解

至此,usart.c文件解读完毕。如果需要在main.c函数里面使用,只需要根据USART_RX_STA中断标志位的状态进行操作即可。

但是对于中断服务这块,HAL库的处理效率低,步骤繁琐,正点原子官方推出另外一个中断处理程序。

void USART1_IRQHandler(void)                	
{ 
	u8 Res;
#if SYSTEM_SUPPORT_OS	 	//使用OS
	OSIntEnter();    
#endif
	if((__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_RXNE)!=RESET))  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	{
        HAL_UART_Receive(&UART1_Handler,&Res,1,1000); 
		if((USART_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
			}
			else //还没收到0X0D
			{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}   		 
	}
	HAL_UART_IRQHandler(&UART1_Handler);	
#if SYSTEM_SUPPORT_OS	 	//使用OS
	OSIntExit();  											 
#endif
} 
#endif	

 更换成这个代码只需要把上面的void USART1_IRQHandler(void)  中断服务函数和voidHAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)回调函数注释即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/673577.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

『手撕 Mybatis 源码』07 - Proxy 对象创建

Proxy 对象创建 问题 sqlSession.getMapper(UserMapper.class) 是如何生成的代理对象? Mapper 代理方式初始化完成后,下一步进行获取代理对象来执行 public class MybatisTest {/*** 问题2:sqlSession.getMapper(UserMapper.class); 是如…

EMC学习笔记(五)传输线模型及反射、串扰

1.概述 在高速数字电路PCB设计中,当布线长度大于20分之一波长或信号延时超过6分之一信号上升沿时,PCB布线可被视为传输线。传输线有两种类型:微带线和带状线。与EMC设计有关的传输线特性包括:特征阻抗、传输延迟、固有电容和固有电感。反射与串扰会影响…

2023年第1季社区Task挑战赛贡献者榜单

基于数字身份凭证的业务逻辑设计,贡献了发放数字身份凭证的参考实现;提供企业碳排放、慈善公益等智能合约库业务场景案例;体验最新发布的WeCross-BCOS3-Stub,跟社区核心开发者碰撞想法并给出自己的见解……这些精彩贡献展现出社区…

<C++项目>高并发内存池

项目介绍: 原型是goole的开源项目tcmalloc(全称:Thread-Caching Malloc),用于替代系统的内存分配相关的函数(malloc, free).知名度非常高。 项目要求知识储备和难度: 会用到C/C、数据结构(链表、哈希桶)、操作系统内存管理、单例模式、多线程、互斥锁等等…

设计模式—“行为变化”

在组件构建过程中,组件行为的变化经常导致组件本身剧烈的变化。“行为变化”模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合。 典型模式有:Command、Visitor 一、Command 动机 在软件构建过程中,"行为请求者"与“行为实现…

看完这篇,立马看懂理想首款纯电MEGA

作者 | 马波编辑 | 德新 6月17日,理想召开了首届家庭科技日活动。 这场打着家庭幌子的科技发布会,信息密度高到有些超出预期。但是看完这场发布会,理想超级旗舰车型 W01,也就是同时在本场发布会公布名称的理想MEGA,它…

硅谷之火重燃武大

关注、星标公众号,直达精彩内容 来源:技术让梦想更伟大 作者:李肖遥 昨天看到雷军雷总在武汉大学的毕业典礼上,朴实的演讲,看似吹牛,实则也是一种勉励。 雷军大学一年级时,在武大图书馆看到一本…

基于java,springboot的音乐分享平台

背景 音乐网站与分享平台的主要使用者分为管理员和用户,实现功能包括管理员:首页、个人中心、用户管理、音乐资讯管理、音乐翻唱管理、在线听歌管理、留言板管理、系统管理,用户:首页、个人中心、音乐翻唱管理、我的收藏管理&…

MySQL - 单表数据量大表优化方案

一. 前言 当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化。 二. 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度,一般以整…

软考:软件工程:软件开发与测试,黑盒测试,白盒测试

软考:软件工程: 提示:系列被面试官问的问题,我自己当时不会,所以下来自己复盘一下,认真学习和总结,以应对未来更多的可能性 关于互联网大厂的笔试面试,都是需要细心准备的 (1&#…

年轻人的储蓄困境:愿望与现实的交锋(原因及解决之道)

年轻人存款难吗?探讨年轻人存款问题是目前社会热议的话题之一。最近的一项调查称,大约五分之一的年轻人存款在一万元以内,而存款超过10万元的年轻人只占总人数的53.7%。这一数据引发了广泛的关注和讨论,究竟是什么原因导致了年轻人…

基于开源项目二次开发KKPrinter实现打印机共享,远程跨网络实现不同网络打印机共享,客户端利用虚拟打印机截取打印文件转发至物理打印机(附源码)

基于开源项目二次开发KKPrinter实现打印机共享,远程跨网络实现不同网络打印机共享,客户端利用虚拟打印机截取打印文件转发至物理打印机(附源码)。实现方案有很多种,这里主要介绍 2 种,并附详细的实现过程和…

MySQL学习笔记之索引优化与查询优化

文章目录 前言数据准备建表创建函数插入数据创建删除索引函数 索引失效案例全值匹配最佳左前缀法则主键插入顺序计算、函数导致列索引失效函数导致索引失效计算导致索引失效 类型转换导致列索引失效范围条件右边的列索引失效不等于导致列索引失效is not null不能使用索引like以…

探索“AI+算力”:加速创新与增长的无限潜力

随着科技的飞速发展,人工智能(AI)技术正成为各行各业的关注焦点。在这个充满激情和创新的时代,"AI算力"的结合应用成为科技行业的热门话题,甚至引发出"AI算力最强龙头"的网络热门等式。本文将探讨…

数据结构-哈希-哈希表实现

哈希表实现 一,哈希概念哈希概念常见哈希函数哈希冲突哈希冲突的解决 二,闭散列实现闭散列的结构插入查找删除闭散列总结 三,哈希桶实现哈希桶的结构插入查找删除析构拷贝构造赋值运算符重载 四,哈希表总结开散列与闭散列的比较哈…

设备虚拟化基础 - PCI

目录 1. 配置空间概念和作用 2. 通过配置空间发现设备 3. Linux读取PCI配置空间接口 4. 内核中具体读取配置空间实例 5. Virtion设备自定义空间 6. Linux读取Capabilities List代码解析 1. 配置空间概念和作用 详细的定义可以参考PCI Spec的第六章《Configuration Space…

嵌入式操作系统(嵌入式学习)

嵌入式操作系统 嵌入式操作系统是什么?嵌入式操作系统有哪些?常用的嵌入式操作系统及其特点对初学者的建议 嵌入式操作系统是什么? 嵌入式操作系统是一种专门设计和优化用于嵌入式系统的操作系统。它是在资源受限的嵌入式设备上运行的操作系…

No CMAKE_Swift_COMPILER could be found问题解决

编译OpenCV的IOS平台包,出错: CMake Error at CMakeLists.txt:20 (enable_language): No CMAKE_Swift_COMPILER could be found. 出错定位,原因是启用Swift语言时没有找到CMAKE_Swift_COMPILER变量 CMAKE官方文档说明启用Swift语言方法 cmake 3.15开始支持swift 查找swift …

简单介绍html/javascript、ajax应用

文章目录 前言1、html1.1.、html实例1.2、HTML文档的后缀名1.3、HTML 编辑器1.4、HTML 标题1.5、HTML 段落1.6、HTML 链接1.7、HTML 图像1.8、HTML 表格1.8.1、HTML 表格实例1.8.2、HTML 表格和边框1.8.3、HTML 表格表头 1.9、HTML <input> 标签1.10、Bootstrap 教程1.10…

开发常用命令合集(Docker、K8s、Linux、Windows等)

开发常用命令合集&#xff08;Docker、K8s、Linux、Windows等&#xff09; 1 Docker 详情查看&#xff1a;https://blog.csdn.net/weixin_45565886/article/details/130130361 1.1 基础命令 ①拉取、查看、删除镜像 docker pull nginx #下载最新版镜像名:版本名&#xff08…