中断系统1 数据传输方式无条件传输 :处理器不必了解外部设备状态,直接进行数据传输,用于指示灯和按键等简单设备.。查询方式 :传输前,一方先查询另一方的状态,若已经准备好就传输,否则就继续查询。中断方式 :一方通过申请中断的方式与另一方进行数据传输,收发双方可以并行工作。直接存储器访问 :处理器内部建立片内外设和内存之间的数据传输通道,传输过程不需要处理器参与。2 中断系统的基本概念2.1 中断全过程中断发生: 当cpu在处理某一事件a时,发生了另一事件b,请求cpu迅速去处理。中断处理: cpu暂停当前的工作,转去处理事件b。中断返回: 当cpu将事件b处理完毕后,再回到事件a中被暂停的地方继续处理事件a。
2.2 中断的作用速度匹配: 可以解决快速的cpu与慢速的外部设备之间传送数据的矛盾。分时操作: cpu可以分时为多个外部设备服务,提高计算机的利用率。实时响应: cpu能够及时处理应用系统的随机事件,增强系统的实时性。可靠性高: cpu可以处理设备故障及掉电等突发事件,提高系统可靠性。2.3 中断优先级处理器根据不同中断的重要程序设置不同的优先等级。
不同优先级中断的处理原则是: 高级中断可以打断低级中断;低级中断不能打断高级中断 。
2.4 中断向量中断服务程序: 在响应一个特定中断的时候,处理器会执行一个函数,该函数一般称为中断处理程序或者中断服务程序。中断向量: 中断服务程序在内存中的入口地址称为中断向量。中断向量表: 把系统中所有的中断向量集中起来放到存储器的某一区。查找中断向量:编号:计算机系统对每一个中断源进行编号,这个号码称为中断类型号。查表:根据中断类型号,到中断向量表中找到对应的表项。执行:取出表项内容,即该中断源对应的中断服务程序地址,进入该程序执行相应操作。2.5 中断响应过程中断源发出中断请求。判断处理器是否允许中断,以及该中断源是否被屏蔽。中断优先级排队。处理器暂停当前程序,保护断点地址和处理器的当前状态,根据中断类型号,查找中断向量表,转到对应的中断服务程序。执行中断服务程序。恢复被保护的状态,执行中断返回指令,回到被中断的程序。3 stm32微控制器中断系统3.1 基本概念中断: 中断是由内核外部产生的,一般由硬件引起,比如外设中断和外部中断等。异常: 异常通常是内核自身产生的,大多是软件引起的,比如除法出错异常、预取值失败等。3.2 nvic嵌套向量中断控制器nvic属于cortex-m内核的组件,管理所有的中断和异常,为中断源分配中断通道
中断向量表
__vectors dcd __initial_sp ; top of stack dcd reset_handler ; reset handler dcd nmi_handler ; nmi handler dcd hardfault_handler ; hard fault handler dcd memmanage_handler ; mpu fault handler dcd busfault_handler ; bus fault handler dcd usagefault_handler ; usage fault handler dcd 0 ; reserved dcd 0 ; reserved dcd 0 ; reserved dcd 0 ; reserved dcd svc_handler ; svcall handler dcd debugmon_handler ; debug monitor handler dcd 0 ; reserved dcd pendsv_handler ; pendsv handler dcd systick_handler ; systick handler ; external interrupts dcd wwdg_irqhandler ; window watchdog dcd pvd_irqhandler ; pvd through exti line detect dcd tamper_irqhandler ; tamper dcd rtc_irqhandler ; rtc dcd flash_irqhandler ; flash dcd rcc_irqhandler ; rcc dcd exti0_irqhandler ; exti line 0 dcd exti1_irqhandler ; exti line 1 dcd exti2_irqhandler ; exti line 2 dcd exti3_irqhandler ; exti line 3 dcd exti4_irqhandler ; exti line 4 dcd dma1_channel1_irqhandler ; dma1 channel 1 dcd dma1_channel2_irqhandler ; dma1 channel 2 dcd dma1_channel3_irqhandler ; dma1 channel 3 dcd dma1_channel4_irqhandler ; dma1 channel 4 dcd dma1_channel5_irqhandler ; dma1 channel 5 dcd dma1_channel6_irqhandler ; dma1 channel 6 dcd dma1_channel7_irqhandler ; dma1 channel 7 dcd adc1_2_irqhandler ; adc1_2 dcd usb_hp_can1_tx_irqhandler ; usb high priority or can1 tx dcd usb_lp_can1_rx0_irqhandler ; usb low priority or can1 rx0 dcd can1_rx1_irqhandler ; can1 rx1 dcd can1_sce_irqhandler ; can1 sce dcd exti9_5_irqhandler ; exti line 9..5 dcd tim1_brk_irqhandler ; tim1 break dcd tim1_up_irqhandler ; tim1 update dcd tim1_trg_com_irqhandler ; tim1 trigger and commutation dcd tim1_cc_irqhandler ; tim1 capture compare dcd tim2_irqhandler ; tim2 dcd tim3_irqhandler ; tim3 dcd tim4_irqhandler ; tim4 dcd i2c1_ev_irqhandler ; i2c1 event dcd i2c1_er_irqhandler ; i2c1 error dcd i2c2_ev_irqhandler ; i2c2 event dcd i2c2_er_irqhandler ; i2c2 error dcd spi1_irqhandler ; spi1 dcd spi2_irqhandler ; spi2 dcd usart1_irqhandler ; usart1 dcd usart2_irqhandler ; usart2 dcd usart3_irqhandler ; usart3 dcd exti15_10_irqhandler ; exti line 15..10 dcd rtc_alarm_irqhandler ; rtc alarm through exti line dcd usbwakeup_irqhandler ; usb wakeup from suspend__vectors_end3.3 中断通道微控制器片内集成了很多外设,对于单个外设而言,它通常具备若干个可以引起中断的中断源,而该外设的所有中断源只能通过指定的中断通道向内核申请中断。
以stm32f103芯片为例,它支持43个可屏蔽中断通道(不包括16个cortex-m3的中断线),已经固定分配给相应的片内外设。由于中断源数量较多,而中断通道有限,会出现多个中断源共享同一个中断通道的情况。
3.4 中断优先级nvic中有一个8位中断优先级寄存器nvic_ipr,理论上可以配置0~255共256级中断。stm32只使用了其中的高4位,并分成抢占优先级和子优先级两组。中断嵌套:
多个中断同时提出中断申请时
先比较抢占优先级,抢占优先级高的中断先执行。如果抢占优先级相同,则比较子优先级。二者都相同时,比较中断编号。编号越小,优先级越高。中断编号位于芯片头文件中。stm32中断优先级分组
hal库初始化函数hal_init将优先级分组设置为第4组,即有0~15,共16级抢占优先级,没有子优先级。编号越小的优先级越高:0号为最高,15号为最低。
3.5 exit外部中断控制器
gpio引脚的外部中断触发方式:
上升沿触发下降沿触发双边沿触发引脚分组:
尾号相同的引脚一组,接入1个外部中断线。同组引脚只能有一个设置为外部中断功能。中断通道:
exti0~exit4分别具有独立的中断通道exti5~exit9共享同一个中断通道exti5~exit9共享同一个中断通道
4 hal库中断处理流程4.1 编程步骤在stm32cubemx中完成
设置中断触发条件设置中断优先等级设能外设中断hal库的接口函数完成
清除中断标志编写中断服务程序4.2 hal库对中断的封装处理统一规定处理各个外设的中断服务程序hal_ppp_irqhandler。在中断服务程序hal_ppp_irqhandler完成了中断标志的判断和清除。将中断中需要执行的操作以回调函数的形式提供给用户。启动文件startup_stm32fxxx.s该文件存放在mdk-arm组中。在该文件中,预先为每个中断编写了一个中断服务程序,只是这些中断服务程序都是死循环,目的只是 初始化中断向量表 ;中断服务程序的属性定义为“weak”。weak属性的函数表示:如果该函数没有在其他文件中定义,则使用该函数;如果用户在其他地方定义了该函数,则使用用户定义的函数。中断服务程序文件:stm32fxxx_it.c该文件存放在user组中,用于 存放各个中断的中断服务程序 ;
在使用cubemx软件进行初始化配置时,如果使能了某一个外设的中断功能,那么在生成代码时,相对应的外设中断服务程序hal_ppp_irqhandler就会自动添加到该文件中,用户只需要在该函数中添加相应的中断处理代码即可。
外部中断所对应的中断服务程序
外部中断线中断服务程序的函数名称
外部中断线0(exti line 0) exti0_irqhandler
外部中断线1(exti line 1) exti1_irqhandler
外部中断线2(exti line 2) exti2_irqhandler
外部中断线3(exti line 3) exti3_irqhandler
外部中断线4(exti line 4) exti4_irqhandler
外部中断线5~9(exti line[9:5]) exti9_5_irqhandler
外部中断线10~15(exti line[15:10]) exti15_10_irqhandler
例如
/** * @brief this function handles exti line0 interrupt. */void exti0_irqhandler(void){ /* user code begin exti0_irqn 0 */ /* user code end exti0_irqn 0 */ hal_gpio_exti_irqhandler(gpio_pin_0); /* user code begin exti0_irqn 1 */ /* user code end exti0_irqn 1 */}4.3 外部中断处理流程假设微控制器芯片为stm32f103,设置引脚pa0为外部中断功能。当引脚pa0出现脉冲边沿时,将触发外部中断。
由于外部中断主要是利用gpio引脚实现,因此外部中断数据类型的定义放在stm32f1xx_hal_gpio.h文件中,外部中断接口函数的实现放在stm32f1xx_hal_gpio.c文件中。
引脚初始化
成员变量mode的取值范围
gpio_mode_it_rising 上升沿触发gpio_mode_it_falling 下降沿触发gpio_mode_it_rising_falling 双边沿触发外部中断通用处理函数hal_gpio_exti_irqhandler
/** * @brief this function handles exti interrupt request. * @param gpio_pin: specifies the pins connected exti line * @retval none */void hal_gpio_exti_irqhandler(uint16_t gpio_pin){ /* exti line interrupt detected */ if (__hal_gpio_exti_get_it(gpio_pin) != 0x00u) { __hal_gpio_exti_clear_it(gpio_pin); hal_gpio_exti_callback(gpio_pin); }}函数原型void hal_gpio_exti_irqhandler(uint16_t gpio_pin)
功能描述 作为所有外部中断发生后的通用处理函数
入口参数 gpio_pin:连接到对应外部中断线的引脚,范围是 gpio_pin_0~gpio_pin_15
返回值 无
注意事项 1. 所有外部中断服务程序均调用该函数完成中断处理2. 函数内部根据gpio_pin的取值判断中断源,并清除对应外部中断线的中断标志3. 函数内部调用外部中断回调函数hal_gpio_exti_callback完成实际的处理任务4. 该函数由cubemx自动生成
外部中断回调函数hal_gpio_exti_callback
/** * @brief exti line detection callbacks. * @param gpio_pin: specifies the pins connected exti line * @retval none */__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 */}函数原型void hal_gpio_exti_callback(uint16_t gpio_pin)
功能描述 外部中断回调函数,用于处理具体的中断任务
入口参数 gpio_pin:连接到对应外部中断线的引脚,范围是 gpio_pin_0~gpio_pin_15
返回值 无
注意事项 1. 该函数由外部中断通用处理函数hal_gpio_exti_irqhandler调用,完成所有外部中断的任务处理2. 函数内部先根据gpio_pin的取值来判断中断源,然后执行对应的中断任务3. 该函数由用户根据实际需求编写
任务实践基于stm32f103c8t6,开发板原理图
利用按键key1改变指示灯led1的闪烁频率,闪烁频率设置为3档:
初始状态时,led1按照1hz的频率闪烁;第一次按键后,led1按照5hz的频率闪烁;第二次按键后,led1按照20hz的频率闪烁,并重复上述过程。注:本任务例程使用的开发板,led1与stm32的pa1相连接,key1与pa0相连接。key1原理图如下:
使用按键时,需要设置pa0为输入上拉模式,这样在key1没有按下时,pa0可以读取到高电平,key1按下时pa0可以读取到低电平。
配置pa0为gpio_exit0,pa1为gpio_output
pa1保持默认gpio输出模式即可
pa0配置为下降沿触发,上拉模式
使能外部中断线
配置中断优先级分组为第四组16级抢占优先级,没有子优先级
以上步骤生成如下代码:
stm32f1xx_hal_gpio.c中生成gpio引脚配置代码,并在main.c中调用
void mx_gpio_init(void){ gpio_inittypedef gpio_initstruct = {0}; /* gpio ports clock enable */ __hal_rcc_gpioa_clk_enable(); __hal_rcc_gpiob_clk_enable(); /*configure gpio pin output level */ hal_gpio_writepin(gpioa, gpio_pin_1, gpio_pin_reset); /*configure gpio pin : pa0 */ gpio_initstruct.pin = gpio_pin_0; gpio_initstruct.mode = gpio_mode_it_falling; gpio_initstruct.pull = gpio_nopull; hal_gpio_init(gpioa, &gpio_initstruct); /*configure gpio pin : pa1 */ gpio_initstruct.pin = gpio_pin_1; gpio_initstruct.mode = gpio_mode_output_pp; gpio_initstruct.pull = gpio_nopull; gpio_initstruct.speed = gpio_speed_freq_low; hal_gpio_init(gpioa, &gpio_initstruct); /* exti interrupt init*/ hal_nvic_setpriority(exti0_irqn, 0, 0); hal_nvic_enableirq(exti0_irqn);}开启外设时钟rcc配置pa0,pa1两个引脚结构体设置exti0中断优先级为0,并使能这个中断stm32fxxx_it.c中生成外设中断服务程序
/** * @brief this function handles exti line0 interrupt. */void exti0_irqhandler(void){ /* user code begin exti0_irqn 0 */ /* user code end exti0_irqn 0 */ hal_gpio_exti_irqhandler(gpio_pin_0); /* user code begin exti0_irqn 1 */ /* user code end exti0_irqn 1 */}编写程序
在main.c中定义指示灯闪烁频率,0代表1hz,1代表5hz,2代表20hz
/* private variables ---------------------------------------------------------*//* user code begin pv */volatile uint8_t speed = 0;/* user code end pv */在main.c中编写应用代码
/* user code begin 3 */ if (speed == 0) { hal_gpio_togglepin(gpioa, gpio_pin_1); hal_delay(1000); } else if (speed == 1) { hal_gpio_togglepin(gpioa, gpio_pin_1); hal_delay(200); } else { hal_gpio_togglepin(gpioa, gpio_pin_1); hal_delay(50); } } /* user code end 3 */在main.c中外部中断回调函数hal_gpio_exti_callback
/* user code begin 4 */ void hal_gpio_exti_callback(uint16_t gpio_pin) { if(gpio_pin == gpio_pin_0) { speed++; if (speed == 3) { speed = 0; } } } /* user code end 4 */
全球2700万辆汽车配备Mobileye技术,助推自动驾驶落地
联想新机将搭载国产双频北斗高精度导航定位SoC芯片HD8040
数据需要获得赋能和拓展,是推动数字经济全域发展之根本
寻找两个正序数组的中位数
三安集团出售1.89%的公司总股本 并获得战略投资者提供的金额约26亿元
STM32基础知识:中断系统
关于孔板/巴类/平衡流量计的介绍
以STM8L15x 芯片为例介绍电压监测电源电压
搭载速腾聚创M系列激光雷达的极氪007开启预售
为什么美国程序员工作比中国程序员工作轻松、加班少?
java高级语言制作智能小车编程实例
机器人咖啡厅在日本开业,由软银机器人提供技术支持
Vivo继续为其Y系列添加新成员
中国通信行业的发展历史以及目前现状
天玑 × 虎牙高能嘉年华燃情谢幕,MediaTek 天玑助力电竞名手决胜赛场
相控阵波束成形IC如何简化天线设计详细解决方法说明
UAVOS成功测试其VTOL无人机的新飞行算法
民生健康将利用区块链技术进行商业创新
FPGA与CPU之间是如何通信的?
探析汇顶科技的核心竞争力与空间