【RoboMaster】细说单片机的中断系统!【STM32】

同步博客地址从STM32开始的RoboMaster生活:进阶篇 II [Interrupt]

项目&教程仓库-STM32-RoboMaster-


1.0 什么是Interrupt?

中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。

  • Interrupt在STM32中大致分为两种,一种就是普通的Interrupt,由外部的外设来打断MCU,另一种名为Exception,是由内部的软件程序自行打断MCU。
  • 要大致理解Interrupt,我们需要了解一下整个运行周期
    1. 首先是,MCU接收到打断信号,但是还没有对该信号做出反应
    2. 然后,当MCU运行完当前的指令后,在fetch下一个指令前,停止当前程序,进入中断
    3. 保存被打断的程序的状态到系统栈,把发起中断的程序的预备状态载入到系统栈,进入该程序
    4. 执行发起中断的程序
    5. 完成后,再把被打断的程序的状态从系统栈加载回来,然后继续执行被打断的程序(全当做无事发生.JPG

2.0 为什么需要Interrupt?

  • 在将Interrupt前,必须提一下Polling。我打个比方,比如有个快递要今天送过来,但你现在正在做RoboMaster,而快递小哥也不知道你长啥样,如果在他来的时候没来人拿,那他就走了,包裹就没了(这个传来的数据是即时的,数据可不会等你)。
  • 如果是Polling,那就是,你一直时不时盯着小区门口,看快递小哥来没来,结果可想而知,可能一整天都没做多少RoboMaster,甚至可能在做的时候,正好小哥来了又走了,结果快递也没拿到。
  • 那有没有办法,可以既能够放心做RoboMaster,又不用担心错过快递呢?这就是Interrupt登场的时候了,方法也很简单,让快递小哥在快递送到的时候给你打个电话(中断信号),你放下手中的RoboMaster任务(被中断),去门口拿快递(执行中断程序),拿完后继续做RoboMaster(继续被中断的任务)就行了。

3.0 STM32内部实现线路 & NVIC

Interrupt Routine.png

NVIC全称为Nested Vectored Interrupt Controller,是STM32专门划分独立出来的模块,专门负责Interrupt事宜,其中技术细节和使用细节非常冗杂,但是实际在RoboMaster中能使用到的部分却是比较简单的,所以本文也不展开细说。

  • 从上图中我们可以看到,NVIC并不是和每个GPIO有单独的线路相连,而是将GPIO分组的,这里与GPIO自己的外设分组不同,并不是PA0,PA1,PA2…为一组,而是PA0,PB0,PC0…为一组,每组共用一根Interrupt信号线,而且更为复杂和迷惑的是,有些特殊情况,比如EXTI10和EXTI15居然在NVIC里面是合并的,但这不用担心,因为就算合并了,STM32也是能分辨具体是从那个组发出的(HAL_GPIO_EXTI_Callback函数能够区分是那个组)。你很可能也猜到了,NVIC是没法分辨每个组内部是那个引脚发出的Interrupt信号,所以在设置芯片的时候,每个组只能有一个引脚能够使用Interrupt。

4.0 Interrupt的生命周期

  • 要谈这个,避免不了要讲讲Priority 优先级

    为使系统能及时响应并处理发生的所有中断,系统根据引起中断事件的重要性和紧迫程度,硬件将中断源分为若干个级别,称作中断优先级。

    在实际系统中,常常遇到多个中断源同时请求中断的情况,这时MCU必须确定首先为哪一个中断源服务,以及服务的次序。解决的方法是中断优先排队,即根据中断源请求的轻重缓急,排好中断处理的优先次序即优先级( Priority ),又称优先权,先响应优先级最高的中断请求。另外,当MCU正在处理某一中断时,要能响应另一个优先级更高的中断请求,而屏蔽掉同级或较低级的中断请求,形成中断嵌套。

  • 中断优先级原则

    1. CPU首先响应高优先级的中断请求;
    2. 如果优先级相同,MCU按查询次序响应排在前面的中断;
    3. 正在进行的中断过程不能被新的同级或低优先级的中断请求所中断;
    4. 正在进行的低优先级中断过程,能被高优先级中断请求所中断。
  • 而在STM32中,又有两种不同的优先级

    • Preempt Priority
      • 也就是我们最常说的常用的Priority,优先级小,越优先,比如优先级如果为负,那就是系统自己的系统中断,比任何用户代码的优先级都高,而用户能够设置的最高的优先级就是0级,其次是1级,2级…
    • Subpriority
      • 主要针对当Preempt Priority相同的情况。
      • 比如,当某个0级程序正在运行时,有1个2级程序发出中断信号,但是因为2级程序的优先级比0级低,所以被Pending 延迟处理了,在0级程序还没运行完的时候,又有一个2级程序发出中断信号,因为同样的原因,也被Pending了,问题来了,当0级程序处理完后,请问先执行那个2级程序呢?当然是,子优先级小的那个。

5.0 如何使用Interrupt

  • 首先是要在配置芯片的时候,给引脚选择EXTI模式
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
   
   
	......
}
  • 在写代码的时候,在main.c中创建HAL_GPIO_EXTI_Callback函数
  • 在该函数中填写如果被中断,需要执行的代码

<项目>/Drivers/STM32F4xx_HAL_Driver/Srcstm32f4xx_hal_gpio.c文件中,我们可以看到其定义

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    
    
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */
}

这里的__weak指明了,该函数如果没被用户创建,就使用上面的代码被默认创建,而如果用户在main.c中自主创建该函数,则用户创建的函数覆盖默认定义的函数。

  • 值得注意的一点是,HAL_GPIO_EXTI_Callback中的uint16_t GPIO_Pin是给用户说明了发出中断信号的是哪个组,正如3.0里面所说,就算EXTI10和EXTI15在NVIC里面是合并的,这个参数也能区分到底是EXTI10还是EXTI15发出的信号,所以不用担心合并后无法区分的问题。

6.0 练习项目

6.1 项目简介

  • 从STM32开始的RoboMaster生活:进阶篇 I [GPIO]里面的项目相同,但是用Interrupt来实现,链接地址

6.2 芯片配置

  • 芯片视角

Chip.png

  • GPIO配置列表

GPIO for RM02.png

  • NVIC配置列表

NVIC for RM02.png

6.3 项目代码

  • 我只放了main.c,完整的工程文件可以在这里找到!

  • Src/main.c

/* USER CODE BEGIN Header */
/**
  ****
### 系统总体架构 基于STM32的海洋环境监测系统是一个集成了传感器技术、嵌入式系统、无线通信和数据处理的综合性系统。其核心是STM32微控制器,通过多种传感器采集环境参数,并通过Wi-Fi、蓝牙等通信模块将数据传输到远程服务器或移动设备上,实现远程监控与管理。系统通常包括以下几个主要模块:传感器采集模块、数据处理模块、通信模块和报警模块[^1]。 ### 传感器采集模块 传感器采集模块负责采集海洋环境中的关键参数,包括水温、湿度、pH值、溶解氧、浑浊度等。常用的传感器包括: - **温度传感器**:如DS18B20,用于监测水温变化[^5]。 - **pH传感器**:如E-201系列pH传感器,用于检测水体酸碱度[^3]。 - **浑浊度传感器**:如TSW-30,用于测量水体的浑浊程度[^3]。 - **溶解氧传感器**:用于监测水中氧气含量,适用于水产养殖和水质监测。 - **烟雾传感器**:如MQ系列传感器,用于检测空气中是否有烟雾或有害气体。 这些传感器将采集到的模拟信号或数字信号传输到STM32微控制器进行处理。 ### 数据处理模块 STM32微控制器作为系统的核心处理单元,负责对传感器采集到的数据进行分析和处理。其主要功能包括: - **数据采集与转换**:对于模拟传感器,STM32通过内部ADC(模数转换器)将模拟信号转换为数字信号;对于数字传感器,STM32直接通过I2C、SPI或UART接口读取数据。 - **数据滤波与校准**:为了提高数据的准确性,系统会对原始数据进行滤波处理,如使用滑动平均法或卡尔曼滤波算法。同时,针对不同传感器的特性,进行校准以消除误差。 - **阈值判断与报警**:系统预设了各个参数的正常范围,当检测到的数值超出设定阈值时,系统触发报警机制,如蜂鸣器报警或LED指示灯闪烁[^5]。 ### 通信模块 通信模块负责将处理后的数据传输到远程终端,以便进行远程监控和管理。常见的通信方式包括: - **Wi-Fi通信**:通过ESP8266或ESP32模块,将数据上传到云端服务器或发送到手机APP,实现远程查看和报警通知。 - **蓝牙通信**:适用于短距离数据传输,用户可以通过蓝牙连接手机或其他设备查看实时数据。 - **LoRa通信**:适用于远距离低功耗通信,适合部署在偏远地区或需要长时间运行的监测点[^4]。 - **GSM/GPRS通信**:在没有Wi-Fi覆盖的区域,可以通过GSM模块发送短信或通过GPRS上传数据。 ### 报警与控制模块 当系统检测到环境参数异常时,会自动触发报警机制,并根据具体情况执行相应的控制操作。例如: - 当水温过低时,系统会自动启动加热装置,直到温度恢复到正常范围。 - 当水温过高时,系统会通过蜂鸣器发出声光报警,并启动增氧设备以改善水质[^5]。 - 当检测到水体浑浊度或pH值异常时,系统可以通过Wi-Fi模块向管理人员发送警报信息,提醒采取相应措施。 ### 显示模块 为了方便现场查看数据,系统通常配备液晶显示屏,如LCD1602或OLED显示屏。这些显示屏可以实时显示当前的环境参数,便于维护人员快速了解系统状态。 ### 系统工作流程 1. 系统启动后,STM32微控制器初始化各个模块,包括传感器、通信模块和显示模块。 2. 传感器开始采集环境参数,并将数据传输到STM32进行处理。 3. STM32对数据进行滤波、校准和分析,判断是否超出预设阈值。 4. 如果数据正常,系统将数据通过Wi-Fi模块上传到云端或手机APP,并在显示屏上显示当前状态。 5. 如果数据异常,系统触发报警机制,并根据具体情况执行相应的控制操作,如启动加热器或增氧设备。 6. 用户可以通过手机APP或Web界面远程查看实时数据,并接收报警通知。 ### 示例代码:STM32数据采集与处理 以下是一个简单的STM32数据采集与处理的示例代码,假设使用DS18B20温度传感器: ```c #include "stm32f10x.h" #include "ds18b20.h" float temperature; int main(void) { // 初始化DS18B20 DS18B20_Init(); while (1) { // 读取温度值 temperature = DS18B20_GetTemp(); // 判断温度是否超出阈值 if (temperature < 20.0) { // 温度过低,启动加热器 GPIO_SetBits(GPIOB, GPIO_Pin_0); } else if (temperature > 25.0) { // 温度过高,触发报警 GPIO_SetBits(GPIOB, GPIO_Pin_1); } else { // 关闭加热器和报警器 GPIO_ResetBits(GPIOB, GPIO_Pin_0); GPIO_ResetBits(GPIOB, GPIO_Pin_1); } // 延时一段时间后再次读取 Delay_ms(1000); } } ``` ### 系统优势 - **高效性**:系统能够实时采集和处理数据,确保管理人员及时掌握环境变化。 - **低成本**:相比传统的人工检测方式,基于STM32系统具有更低的成本和更高的自动化程度。 - **可扩展性**:系统可以根据需求添加更多传感器和功能模块,如GPS定位、摄像头监控等。 - **远程监控**:通过Wi-Fi或LoRa等通信方式,实现远程数据传输和报警通知,提升管理效率。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值