IRQ Handler 的使用——以USART串口接收中断分别在标准库与HAL库版本下的举例

 前言:

1.中断系统及EXTI外部中断知识点见我的博文:

9.中断系统、EXTI外部中断_eirq-CSDN博客文章浏览阅读301次,点赞7次,收藏6次。EXTI(Extern Interrupt)外部中断EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序。引脚电平变化,申请中断支持的触发方式(引脚电平的变化类型):上升沿(电平从低电平变到高电平的瞬间触发中断)/下降沿(电平从高电平变到低电平的瞬间触发中断)/双边沿(上升沿和下降沿都可以触发中断)/软件触发(程序执行代码就能触发中断)_eirqhttps://blog.csdn.net/m0_61712829/article/details/132433502?spm=1001.2014.3001.55022.本文重点讲USART串口接收中断分别在标准库和HAL库版本下如何使用,其它例如串口初始化程序就不重点阐述了。


 IRQ(Interrupt Request)是一种用于请求中断服务的机制,IRQ Handler就是负责处理IRQ中断的中断处理程序。

 “IRQHandler” 是中断处理程序的意思。中断处理程序是在计算机系统遇到硬件中断时执行的函数或程序代码。硬件中断可以由外部设备(如键盘、鼠标或计时器)触发,也可以由内部事件(如除零错误或内存故障)触发。 当一个中断事件发生时,操作系统会暂停当前的执行任务,跳转到相应的中断处理程序中执行。中断处理程序通常用于处理和响应中断事件,采取必要的操作来处理中断,并在完成后返回到中断发生的地方继续执行。

当串口接收到数据时,可以配置USART串口使用中断来触发数据接收中断。当接收到数据时,中断处理程序会被调用,可以在其中读取接收到的数据并进行处理。使用中断可以避免轮询方式的查询接收,提高实时性和效率。

使用标准库--USART串口接收中断

1.在usart.c文件中写中断接收和变量的封装函数并重写USART1中断函数接受字符串数据函数。代码如下:

/*** @brief       中断接收和变量的封装函数* @param       无* @retval      无*/
uint8_t Serial_GetRxFlag(void)//读后自动清除标志位
{if(usart1_RxFlag == 1){usart1_RxFlag = 0;return 1;}return 0;
}uint8_t Serial_GetRxData(void)
{return usart1_RxData;
}/*** @brief       重写USART1中断函数接受字符串数据* @param       无* @retval      无*/void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET){usart1_RxData = USART_ReceiveData(USART1);usart1_RxFlag = 1;USART_ClearITPendingBit(USART1,USART_IT_RXNE);}}

uint8_t Serial_GetRxFlag(void)函数解释如下。

  1. 判断usart1_RxFlag变量是否为1,表示接收到了新的数据。
  2. 如果接收到了新的数据,将usart1_RxFlag变量置为0,表示接收标志位已被清除。
  3. 返回1,表示接收到了新的数据。
  4. 如果没有接收到数据,返回0。

uint8_t Serial_GetRxData(void)函数解释如下。

  1. 该函数用于获取接收到的数据。
  2. 直接返回usart1_RxData变量,该变量存储了接收到的数据。

void USART1_IRQHandler(void)函数解释如下。

  1. 该函数是重写的USART1中断处理函数,用于接收字符串数据。
  2. 通过判断USART1的接收中断标志位USART_IT_RXNE是否被置位,确定是否接收到了新的数据。
  3. 如果接收到了新的数据,使用USART_ReceiveData()函数从USART1接收数据,并将数据存储到usart1_RxData变量中。
  4. usart1_RxFlag变量置为1,表示接收到了新的数据。
  5. 使用USART_ClearITPendingBit()函数清除USART1的接收中断标志位。 需要注意的是,以上代码中的函数调用和变量使用可能依赖于库函数和全局变量的定义,确保在使用这些函数之前进行适配,且USART1已正确初始化和配置中断。

2.在main.c中的main函数的while(1)循环中,定义串口中断接收函数。代码如下,这部分代码是在使用串口接收数据并进行处理的部分。

uint8_t RXData;//串口1接收数据...省略
usart1_Init();//串口1初始化
.../*** @brief       串口1接收数据*   @ntoe      * @param       无* @retval      无*/        if(Serial_GetRxFlag() == 1) {RXData = Serial_GetRxData();Serial_SendByte(RXData);//数据回传功能,将接收到的这一字节数据回传到电脑OLED_ShowHexNum(1,8,RXData,2);}    

首先,声明了一个RXData变量用于保存串口1接收到的数据。 然后,调用了usart1_Init()函数进行串口1的初始化设置。 接下来是一个条件判断语句,通过调用Serial_GetRxFlag()函数判断是否接收到了新的数据。 如果接收到了新的数据,执行以下操作:

  1. 调用Serial_GetRxData()函数获取接收到的数据,将其存储到RXData变量中。
  2. 调用Serial_SendByte(RXData)函数将接收到的数据回传到电脑。
  3. 调用OLED_ShowHexNum(1,8,RXData,2)函数在OLED屏幕上显示接收到的数据的十六进制形式。 需要注意的是,以上代码中的函数调用和变量使用可能依赖于其他部分的定义和实现,确保在使用之前进行适配,且串口1已正确初始化和配置。

 

3.串口接收数据测试。在main.c中的main函数的while(1)循环前,借用oled显示屏来显示接收到的串口数据。使用如下代码:

        OLED_ShowString(1,1,"RxData:");//串口1接收数据测试

使用HAL库--USART串口接收中断

1.在stm32f1xx_it.c文件中,写void USART2_IRQHandler(void)函数。当USART2的中断发生时,系统会自动跳转到这个函数进行处理。

/*** @brief This function handles USART2 global interrupt.*/
void USART2_IRQHandler(void)
{/* USER CODE BEGIN USART2_IRQn 0 */uart2_receiver_handle();/* USER CODE END USART2_IRQn 0 */HAL_UART_IRQHandler(&huart2);/* USER CODE BEGIN USART2_IRQn 1 *//* USER CODE END USART2_IRQn 1 */
}

解释如下:

  1. uart2_receiver_handle();:这是用户自定义的函数,用于处理USART2接收到的数据。在USART2接收到数据时,该函数将被调用,用户可在该函数内部处理接收到的数据。
  2. HAL_UART_IRQHandler(&huart2);:这是调用HAL库函数的代码,用于处理USART2的中断。HAL库是一种硬件抽象层库,用于简化嵌入式系统的开发。该函数会处理USART2的中断,并根据具体情况执行相应的操作,如处理发送和接收缓冲区、错误处理等。 在这段代码中,用户可以根据自己的需求,在"USER CODE"注释处插入额外的代码来处理特定的操作或事件。例如,可以在USART2接收到数据后,根据接收的数据进行一些特定的处理,如解析命令、更新状态等。 需要注意的是,以上代码是一段模板代码,具体的操作和功能取决于用户自定义的函数和使用的USART2的配置。用户需要根据具体的需求,在USART2_IRQHandler函数和uart2_receiver_handle()函数中实现自己所需要的功能。

2.然后在usart.c文件中写串口数据接收处理与数据接收清0函数。

unsigned char receive_buf[512];	  //串口2接收缓存数组
unsigned char receive_start = 0;	//串口2接收开始标志位
uint16_t receive_count = 0;	      //串口2接收数据计数器
uint16_t receive_finish = 0;	    //串口2接收结束标志位 /*** @brief          串口2数据接收处理函数* @param[in]      none* @retval         none*/
void uart2_receiver_handle(void)
{unsigned char receive_data = 0;   if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_RXNE) != RESET){ HAL_UART_Receive(&huart2, &receive_data, 1, 1000);//串口2接收1位数据receive_buf[receive_count++] = receive_data;receive_start = 1;	                              //串口2接收数据开始标志位置1receive_finish = 0;	                              //串口2接收数据完成标志位清0}
}
/*** @brief          串口2数据接收清0函数* @param[in]      len:清空的数据长度* @retval         none*/
void uart2_receiver_clear(uint16_t len)	
{memset(receive_buf,0x00,len);receive_count = 0;receive_start = 0;receive_finish = 0;
}

以上函数中的关键步骤如下: 

  1. 声明一个无符号字符变量receive_data,用于保存接收到的数据。
  2. 通过判断UART2的接收标志位UART_FLAG_RXNE是否被置位,确定是否接收到了数据。
  3. 如果接收到了数据,使用HAL库函数HAL_UART_Receive()从UART2接收1个字节的数据,并存储到receive_data变量中。
  4. 将接收到的数据存储到一个接收缓冲区receive_buf[]中,使用receive_count变量记录接收到的数据字节数。
  5. 设置receive_start变量为1,表示串口2开始接收数据。
  6. 清零receive_finish变量,表示串口2接收数据还未完成。 然后是uart2_receiver_clear()函数,该函数用于清空接收缓冲区的数据。函数中的关键步骤如下:
  7. 使用memset()函数将接收缓冲区receive_buf[]中的数据清零,长度为len
  8. receive_countreceive_startreceive_finish变量都重新赋值为0,表示接收缓冲区已清空,接收数据未开始。 这两个函数可以根据具体需求进行使用,如根据receive_countreceive_buf[]中的数据进行进一步处理、解析等。需要注意的是,以上代码中的函数调用和变量使用可能依赖于库函数和全局变量的定义,确保在使用这些函数之前进行适配,且串口2已正确初始化和配置。

3.根据串口接收开始标志位,进行使用串口接收中断。如上程序中使用到的标志位receive_start,为1则开始串口接收数据。在当判断标志位为1时,执行相应的功能程序就可以了。使用如下代码:
        if(receive_start == 1)    {.....}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis(认识NoSQL,认识redis,安装redis,redis桌面客户端,redis常见命令,redis的Java客户端)

文章目录 Redis快速入门1.初识Redis1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结 1.2.认识Redis1.3.安装Redis1.3.1.依赖库1.3.2.上传安装包并解压1.3.3.启动1.3.4.默认启动1.3.5.指定配置启动1.3.6.开机自启 1.4.Redis桌面客户端…

病情聊天机器人,利用Neo4j图数据库和Elasticsearch全文搜索引擎相结合

项目设计目的: 本项目旨在开发一个病情聊天机器人,利用Neo4j图数据库和Elasticsearch全文搜索引擎相结合,实现对病情相关数据的存储、查询和自动回答。通过与用户的交互,机器人可以根据用户提供的症状描述,给出初步的可…

Linux---进程控制

一、进程创建 fork函数 在Linux中fork函数是非常重要的函数,它从已存在进程中创建一个新进程,原进程为父进程 fork函数的功能: 分配新的内存和内核数据结构给子进程将父进程部分数据结构内容拷贝至子进程添加子进程到系统的进程列表中fork返…

听GPT 讲Rust源代码--library/portable-simd

File: rust/library/portable-simd/crates/core_simd/examples/spectral_norm.rs spectral_norm.rs是一个示例程序,它展示了如何使用Portable SIMD库中的SIMD(Single Instruction Multiple Data)功能来实现频谱规范化算法。该示例程序是Rust源…

如何使用SeaFile搭建本地私有云盘并结合cpolar实现远程访问

文章目录 1. 前言2. SeaFile云盘设置2.1 SeaFile的安装环境设置2.2 SeaFile下载安装2.3 SeaFile的配置 3. cpolar内网穿透3.1 Cpolar下载安装3.2 Cpolar的注册3.3 Cpolar云端设置3.4 Cpolar本地设置 4.公网访问测试5.结语 1. 前言 现在我们身边的只能设备越来越多,…

从零开始:使用 BIND 构建和管理您的 DNS 服务器

1 前言 在这篇文章中,我将详细介绍如何使用 BIND(Berkeley Internet Name Domain)软件包中的 named 程序来配置和管理一个基本的 DNS 服务器。 从安装 BIND 开始,到设置 DNS 区域文件,再到运行和测试您的服务器&#x…

typescript 中 infer 用法

infer 介绍 infer 一般在 extends 子语句中,infer 会引入一个待推断的类型变量 (如 infer R) R可以是任意单词字母 这个推断的类型变量可以在有条件类型的 true 分支中被引用 允许出现多个同类型变量的 infer。 基本示例 type ParamType<T> T extends (arg: infer…

kubeadm创建k8s集群

kubeadm来快速的搭建一个k8s集群&#xff1a; 二进制搭建适合大集群&#xff0c;50台以上。 kubeadm更适合中下企业的业务集群。 部署框架 master192.168.10.10dockerkubelet kubeadm kubectl flannelnode1192.168.10.20dockerkubelet kubeadm kubectl flannelnode2192.168.1…

新火种AI|福布斯Top50,估值高达50亿,这家AI法律公司令人震惊

2023年3月&#xff0c;OpeAI以雷霆之势推出了ChatGPT&#xff0c;为AI产业带来了颠覆性的进展&#xff0c;让所有人为之震惊。其中有一项对于ChatGPT的测试还引起了了不小的轰动&#xff0c;当时美国伊利诺伊理工大学芝加哥肯特法学院称&#xff0c;GPT-4通过了美国律师资格考试…

嵌入式视频播放器(mplayer)

1.文件准备&#xff1a; MPlayer-1.0rc2.tar.bz2 libmad-0.15.1b.tar.gz 直接Git到本地 git clone https://gitee.com/zxz_FINE/mplayer_tarball.git 2.文件夹准备&#xff1a; src存放解压后的源码文件&#xff0c;target_Mplayer存放编译安装的目标文件 mkdir src targe…

将本地工作空间robot_ws上传到gitee仓库

git config --global user.name "geniusChinaHN" git config --global user.email "12705243geniuschinahnuser.noreply.gitee.com" cd ~/robot_ws #git init#创建原始仓库时候用 git add . git commit -m "上传文件内容描述" #git remote add r…

​iOS实时查看App运行日志

目录 一、设备连接 二、使用克魔助手查看日志 三、过滤我们自己App的日志 &#x1f4dd; 摘要&#xff1a; 本文介绍了如何在iOS iPhone设备上实时查看输出在console控制台的日志。通过克魔助手工具&#xff0c;我们可以连接手机并方便地筛选我们自己App的日志。 &#x1f4…

009:vue结合el-table实现表格行拖拽排序(基于sortablejs)

文章目录 1. 实现效果2. 安装 sortablejs 插件3. 完整组件代码4. 注意点 1. 实现效果 2. 安装 sortablejs 插件 sortablejs 更多用法 cnpm i --save sortablejs3. 完整组件代码 <template><div class"home"><div class"body"><el-ta…

pytorch深度学习笔记(共计169页,基于本人听完B站小土堆PyTorch深度学习快速入门教程所写)

一、笔记视频 pytorch深度学习&#xff08;共计169页&#xff0c;基于本人听完B站小土堆PyTorch深度学习快速入门教程所写&#xff09; 二、获取方式 方式一&#xff1a; 点击下面的链接 pytorch深度学习笔记 如果链接无法打开 直接复制下方链接即可 https://mall.bilibili.c…

appium入门基础

介绍 appium支持在不同平台的UI自动化&#xff0c;如web,移动端,桌面端等。还支持使用java&#xff0c;python&#xff0c;js等语言编写自动化代码。主要用于自动化测试脚本&#xff0c;省去重复的手动操作。 Appium官网 安装 首先必须环境有Node.js用于安装Appium。 总体来…

【前缀和】【分类讨论】【二分查找】2983:回文串重新排列查询

作者推荐 【动态规划】【字符串】C算法&#xff1a;正则表达式匹配 本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 二分查找算法合集 回文串重新排列查询 给你一个长度为 偶数 n &#xff0c;下标从 0 开始的字符…

Pandas数据可视化

pandas库是Python数据分析的核心库 它不仅可以加载和转换数据&#xff0c;还可以做更多的事情&#xff1a;它还可以可视化 pandas绘图API简单易用&#xff0c;是pandas流行的重要原因之一 Pandas 单变量可视化 单变量可视化&#xff0c; 包括条形图、折线图、直方图、饼图等 …

精确率(Precision,P),召回率(Recall,R)以及F1值(F1-score,F1)

狗狗识别系统的例子&#xff1a; 假设我们有两个集合&#xff1a; 实际狗狗的集合&#xff08;实际真正是狗狗的图片&#xff09;&#xff1a;A我们识别为狗狗的集合&#xff08;我们认为是狗狗的图片&#xff09;&#xff1a;B 精确率&#xff08;Precision&#xff0c;P&am…

Codeium在IDEA里的3个坑

转载自Codeium在IDEA里的3个坑&#xff1a;无法log in&#xff0c;downloading language server和中文乱码_downloading codeium language server...-CSDN博客文章浏览阅读1.7w次&#xff0c;点赞26次&#xff0c;收藏47次。Codeium安装IDEA插件的3个常见坑_downloading codeiu…

一文初识Linux进程(超详细!)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;HEART BEAT—YOASOBI 2:20━━━━━━️&#x1f49f;──────── 5:35 &#x1f504; ◀️ ⏸ ▶️ ☰ …