一、背景 有个需求,IO口检测上升沿,然后做相应的动作。在此记录STM32F103的外部中断结构及配置方法, 以备下次快速上手使用。 有许多不太明白,又是老司机(:-D)帮忙,真的是站在别人的肩膀上会让你看的更远,走的更快, 感谢老司机。 二、正文 STM32f103有68个可屏蔽中断。(但是,真正能用的其实远没有这么多,原因下面会详述。) 有16个可编程的优先等级,优先等级的概念可详见我的另外一篇博客《STM32 之 NVIC(中断向量、 优先级)简述》,链接:"http://www.cnblogs.com/ChYQ/p/5859974.html",接着看中断向量表, 如下图:
该中断向量表从高到低按照默认的中断优先级排序将所有可用的中断以表的形式列出来。仔细来看 每一列代表的意义: "优先级":无需多言,默认的中断优先级次序。 "优先级类型":即表明,这个对应的默认优先级是否可被配置更改,以使其优先级升高或者降低。 "名称":外部中断名称简写 "说明":通过这个我们就可以清楚知道前一列的"名称"代表的是哪个具体的外设中断。 "地址":这个地址即当对应的外部中断来时,若是使能了该外部中断,则MCU会将PC指针跳转到该 地址,编译器一般会在该地址内保存对应的中断处理函数指针,进而可进入到相应的中断 处理函数做相应的处理。 然后说说外部中断事件(EXTI),外部中断事件由20个(互联型)/19个产生事件/中断的边沿检测器组 成,白话说,即GPIO口可检测到对应IO口的上升沿/下降沿/双边沿事件,进而产生相应中断。 接着看外部中断/时间框图,如下图:
从最右来看,输入线连接至GPIO口,检测外部引脚的电平信号,上升沿/下降沿触发器与软件中断 事件触发器,经过"或"器件传入下一级,意味着,这两类信号可独立引起中断/事件。经过"或"后,信 号出现了分支,信号一路进入请求挂起寄存器,若是中断屏蔽寄存器设置为允许该信号,则一起"与"使 能对应的中断。另一路则是同事件屏蔽寄存器信号相"与",通过则产生对应的事件。 说到这,中断和事件又有什么不同呢? 中断既是正常理解的中断,中断信号通过后,会让MCU的PC值跳转到相应的中断入口,找到对应的 中断处理函数,然后进行中断处理。 事件则用来向其他外设模块发送脉冲事件,通知外设去做相应的事情,就以ADC接收到脉冲事件后自动 开始ADC转换为例进行说明。 在ADC中,初始化ADC的结构体如下: typedef struct { uint32_t ADC_Mode; FunctionalState ADC_ScanConvMode; FunctionalState ADC_ContinuousConvMode; uint32_t ADC_ExternalTrigConv; uint32_t ADC_DataAlign; uint8_t ADC_NbrOfChannel; }ADC_InitTypeDef; 选项"ADC_ExternalTrigConv",即是设置ADC的触发启动方式,可配置为软件触发启动,当该值配置为 "ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO"的时候,则ADC会在EXT产生脉冲事件的同时,开始自动 触发ADC转换,与软件触发启动不同的是,这种方式是硬件自动完成,不需要软件参与。当然,不限定 只能为EXT,还可以是定时器等等。 最后说说上文提及的,为什么明明有68个可屏蔽中断,可实际却远没有这么多。 上图提及,GPIO口通过连接到外部中断/事件线上来完成相应的中断请求,然后看看外部中断通用 I/O口映像,如下图:
外部中断/事件线只有16个,IO口却有A~G(7)组,每组有16个引脚,从上图可看出,实际上一次性 可用的外部中断/事件也只能有16个,并不是IO口有多少,就能有多少个外部中断/事件。 譬如说若是第一组PA0用了第一个中断/事件线,那么P(x)0就不能再被用作外部中断输入口了。(x 为B~G)。 外部中断结构大致就介绍到此。接下来说说,结合库函数,如何让外部中断配置成功并工作。一 一般步骤为: --> 初始化对应IO口为输入; --> 使能对应IO口时钟,并设定IO口与外部中断/事件线的联系; 注意:由于此处用了外部中断,所以对应的复用时钟要打开! RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 使能GPIO时钟复用 // 设定GPIO口与中断/事件线联系库函数 void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); "GPIO_PortSource":选择对应的GPIO口。 "GPIO_PinSource" :选择对应的外部中断/事件线。 --> 初始化外部中断/事件线,并配置触发模式(上边沿/下边沿/双边沿); void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) 结构体"EXTI_InitStruct"如下: typedef struct { // 外部中断/事件线是否被使能 // "EXTI_Line0"->"EXTI_Line15" uint32_t EXTI_Line; // 中断模式/事件模式 EXTIMode_TypeDef EXTI_Mode; // 触发模式(上边沿/下边沿/双边沿) EXTITrigger_TypeDef EXTI_Trigger; // "Enable"或"Disable" FunctionalState EXTI_LineCmd; }EXTI_InitTypeDef; --> 设置NVIC,并使能中断; 详见NVIC博客,不再详述 --> 写中断处理函数。 STM32F103外部中断函数共有6个: EXTI0_IRQHandler EXTI1_IRQHandler EXTI2_IRQHandler EXTI3_IRQHandler EXTI4_IRQHandler EXTI9_5_IRQHandler EXTI15_10_IRQHandler 外部中断"0"->"4"有独立的中断处理函数; 外部中断"5"->"9"共用中断函数"EXTI9_5_IRQHandler"; 外部中断"10"->"15"共用中断函数"EXTI15_10_IRQHandler"; 中断函数示例如下: void EXTI9_5_IRQHandler(void) { // 获取中断状态 if(EXTI_GetITStatus(EXTI_IMR_MR8) != RESET) { // 清除挂起位 EXTI_ClearITPendingBit(EXTI_IMR_MR8); } } 三、参考链接 STM32 external interrupt http://www.programering.com/a/MDM4kzMwATg.html STM32 外部中断学习笔记 http://blog.csdn.net/zzwdkxx/article/details/9036679 至此,记录完毕。
上一篇:stm32启动文件 startup_stm32f10x_hd.s
下一篇:如何快速上手使用STM32库函数
推荐阅读最新更新时间:2024-03-16 15:27