完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
利用外部中断来实现按键控制LED灯的亮灭。
实验工具:MDK5,STM32F103ZET6开发板 使用固件库编程 LED灯引脚PD13,按键PE0 首先了解一下32的外部中断 STM32 的每个 IO 都可以作为外部中断的中断输入口,STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状位,每个中断/事件都有独立的触发和屏蔽设置。 STM32F103的 19 个外部中断为: 线 0~15:对应外部 IO 口的输入中断。 线 16:连接到 PVD 输出。 线 17:连接到 RTC 闹钟事件。 线 18:连接到 USB 唤醒事件。 所以这次要用到的就是线 0~15。 下图是IO口语中断线的一一映射关系 以线 0 为例:它对应了 GPIOA.0、 GPIOB.0、 GPIOC.0、GPIOD.0、GPIOE.0、 GPIOF.0、 GPIOG.0 使用外部中断的配置过程 在此之前先写一个LED与按键KEY的程序 led.c #include "led.h" void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStrtuct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); GPIO_InitStrtuct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStrtuct.GPIO_Pin = GPIO_Pin_13; GPIO_InitStrtuct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD,&GPIO_InitStrtuct); } key.c #include "key.h" void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStrtucter; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); GPIO_InitStrtucter.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStrtucter.GPIO_Pin = GPIO_Pin_0; GPIO_Init(GPIOE,&GPIO_InitStrtucter); } uint8_t Key_scan(void) { if (KEY == 1) { //松手检测 while(KEY == 1) return 1; } else return 0; } 然后就可以根据上面的步骤一步步配置中断了 #include "exti.h" #include "key.h" #include "delay.h" #include "led.h" void EXTIX_Init(void) { EXTI_InitTypeDef EXTI_InitStruct; NVIC_InitTypeDef NVIC_InitStructer; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟 KEY_Init();//初始化按键 //中断线的映射以及中断初始化配置 GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource0);//中断线映射函数 EXTI_InitStruct.EXTI_Line = EXTI_Line0; EXTI_InitStruct.EXTI_LineCmd = ENABLE; EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 模式为interrupt EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发 EXTI_Init(&EXTI_InitStruct); //配置中断分组并使能中断 NVIC_InitStructer.NVIC_IRQChannel = EXTI0_IRQn; //使能按键所在的外部中断通道 NVIC_InitStructer.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_InitStructer.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2 NVIC_InitStructer.NVIC_IRQChannelSubPriority = 0x02; //子优先级1 NVIC_Init(&NVIC_InitStructer); } //中断服务函数 void EXTI0_IRQHandler() { delay_ms(10); //消抖 if(KEY==1) { LED=!LED; } EXTI_ClearITPendingBit(EXTI_Line0); //清除EXTI0线路标志位 } 说明一下 NVIC_InitStructer.NVIC_IRQChannel = EXTI0_IRQn; 它的配置是在stm32f10x.h里面, PxN管脚共用外部中断线EXTIN和外部中断向量EXTIN_IRQn和中断服务程序入口EXTIN_IRQHandler,但是需要注意[9…5]共用EXTI9_5_IRQn和EXTI9_5_IRQHandler、[15…10]共用EXTI15_10_IRQn和EXTI15_10_IRQHandler。 而中断服务函数void EXTI0_IRQHandler()是在 startup_stm32f10x_hd.s 里面 有关中断分组 具体的分配关系如表 所示: 抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。 这里需要注意两点: 第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行; 第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级 中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。 结合实例说明一下: 假定设置中断优先级组为 2,然后设置中断 3(RTC 中断)的抢占优先级为 2,响应优先级为 1。中断 6(外部中断 0)的抢占优先级为 3,响应优先级为 0。中断 7(外部中断 1)的抢占优先级为 2,响应优先级为 0。 那么这 3 个中断的优先级顺序为:中断 7>中断 3>中断 6。 上面例子中的中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3 却不可以相互打断! 结论: 1.抢占优先级越小,优先级越高;相同抢占优先级的中断不能相互打断; 2.相同抢占优先级N个中断发生时,响应优先级越小的中断首先执行,如果响应优先级也均相同,则根据各中断对应向量表的位置来确定,向量表中越靠前的中断先响应。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1792 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1626 浏览 1 评论
1094 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
732 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1682 浏览 2 评论
1943浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
740浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
577浏览 3评论
600浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
562浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-26 01:26 , Processed in 0.716067 second(s), Total 47, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号