完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
注:博客所涉及的关于 stm32 的代码,均在仓库【stm32f013_study】下,包括底层驱动和应用测试代码。
本文设计的文件包含: (1)源文件: drvexti.c:外部中断驱动实现 (2)头文件: drvexti.h : 外部中断驱动头文件 1. STM32 外部中断简介 STM32 的每个 IO 都可以作为外部中断的中断输入口。 STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。代码主要分布在固件库的 stm32f10x_exti.h 和 stm32f10x_exti.c 文件。 STM32F103的 19 个外部中断为: 触发方式:STM32 的外部中断是通过边沿来触发的,不支持电平触发。 2. 外部中断分组 STM32 的每一个 GPIO 都能配置成一个外部中断触发源,STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组。 比如:PA0,PB0,PC0,PD0,PE0,PF0,PG0 为第一组。 依此类推,我们能得出一共有16 组,STM32 规定,每一组中同时只能有一个中断触发源工作,那么,最多工作的也就是16个外部中断。 3. 使用 IO 口外部中断的配置步骤 3.1 初始化 IO 口为输入 设置作为外部中断输入的 IO 口的状态,可以设置为上拉 / 下拉输入 / 浮空输入,但浮空的时候外部一定要带上拉,或者下拉电阻。否则可能导致中断不停的触发。在干扰较大的地方,就算使用了内部上拉/下拉,也建议使用外部上拉/下拉电阻,这样可以一定程度防止外部干扰带来的影响。 3.2 开启 IO 口复用时钟,设置 IO 口与中断线的映射关系 STM32 的 IO 口与中断线的对应关系需要配置外部中断配置寄存器 EXTICR,这样我们要先开启复用时钟,然后配置 IO 口与中断线的对应关系。才能把外部中断与中断线连接起来。 3.3 开启与该IO口相对的线上中断/事件,设置触发条件 配置中断产生的条件,STM32 可以配置成上升沿触发,下降沿触发,或者任意电平变化触发,但是不能配置成高电平触发和低电平触发。同时要开启中断线上的中断。 注意: 如果使用外部中断,并设置该中断的 EMR 位的话,会引起软件仿真不能跳到中断,而硬件上是可以的。而不设置 EMR,软件仿真就可以进入中断服务函数,并且硬件上也是可以的。建议不要配置 EMR 位。 3.4 配置中断分组NVIC 配置中断的分组,以及使能,对 STM32 的中断来说,只有配置了 NVIC 的设置,并开启才能被执行,否则是不会执行到中断服务函数里面去的。 3.5 编写中断服务函数 这是中断设置的最后一步,中断服务函数,是必不可少的,如果在代码里面开启了中断,但是没编写中断服务函数,就可能引起硬件错误,从而导致程序崩溃!所以在开启了某个中断后,一定要记得为该中断编写服务函数。在中断服务函数里面编写你要执行的中断后的操作。 4. 例程分析 4.1 配置外部中断对应IO //--------------------------------------------------------------------------------------------------------------------------------------------- // 函 数 名: exti_gpio_config // 功能说明: 外部中断GPIO参数配置 // 形 参: 无 // 返 回 值: 无 // 日 期: 2020-04-25 // 备 注: // 作 者: by 霁风AI //--------------------------------------------------------------------------------------------------------------------------------------------- static void exti_gpio_config(void) { GPIO_InitTypeDef gpio_init_config; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PORTA时钟 gpio_init_config.GPIO_Pin = GPIO_Pin_0;//PA0 gpio_init_config.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉 GPIO_Init(GPIOA, &gpio_init_config);//初始化GPIOA.0 } 4.2 配置外部中断参数 //--------------------------------------------------------------------------------------------------------------------------------------------- // 函 数 名: exti_config // 功能说明: 外部中断参数配置 // 形 参: 无 // 返 回 值: 无 // 日 期: 2020-04-25 // 备 注: // 作 者: by 霁风AI //--------------------------------------------------------------------------------------------------------------------------------------------- static void exti_config(void) { EXTI_InitTypeDef exti_init_config; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //外部中断,需要使能AFIO时钟 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //PA0设置为外部中断 exti_init_config.EXTI_Line = EXTI_Line0; exti_init_config.EXTI_Mode = EXTI_Mode_Interrupt; exti_init_config.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发 exti_init_config.EXTI_LineCmd = ENABLE; EXTI_Init(&exti_init_config); //根据EXTI_InitTypeDef中指定的参数初始化外设EXTI寄存器 } 4.3 配置中断向量 //--------------------------------------------------------------------------------------------------------------------------------------------- // 函 数 名: exit_nvic_config // 功能说明: 中断向量参数配置 // 形 参: 无 // 返 回 值: 无 // 日 期: 2020-04-25 // 备 注: // 作 者: by 霁风AI //--------------------------------------------------------------------------------------------------------------------------------------------- static void exti_nvic_config(void) { NVIC_InitTypeDef nvic_init_config; nvic_init_config.NVIC_IRQChannel = EXTI0_IRQn;//使能按键所在的外部中断通道 nvic_init_config.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2 nvic_init_config.NVIC_IRQChannelSubPriority = 0x02;//子优先级1 nvic_init_config.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic_init_config); } 4.4 统一外部中断调用接口 //--------------------------------------------------------------------------------------------------------------------------------------------- // 函 数 名: exti_init // 功能说明: 外部中断初始化 // 形 参: exti_no:中断号 // 返 回 值: 无 // 日 期: 2020-04-25 // 备 注: 外部调用此函数,实现EXTI的初始化配置 // 作 者: by 霁风AI //--------------------------------------------------------------------------------------------------------------------------------------------- void exti_init(uint8_t exti_no) { if (exti_no == 0) { exti_gpio_config(); exti_config(); exti_nvic_config(); } } 4.5 编写中断服务函数 //--------------------------------------------------------------------------------------------------------------------------------------------- // 函 数 名: EXTI0_IRQHandler // 功能说明: 外部中断0服务函数 // 形 参: 无 // 返 回 值: 无 // 日 期: 2020-04-25 // 备 注: // 作 者: by 霁风AI //--------------------------------------------------------------------------------------------------------------------------------------------- void EXTI0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line0) != RESET) { g_exti_cnt++; if (g_exti_cnt % 2) { Bsp_LedOn(0); //点亮OLED0 } else { Bsp_LedOff(0); //熄灭OLED0 } if (g_exti_cnt 》 200) { g_exti_cnt = 0; } EXTI_ClearITPendingBit(EXTI_Line0); //清除EXTI0线路挂起 } } 补充: 在编写中断服务函数的时候会经常使用到两个函数。 (1)第一个函数是判断某个中断线上的中断是否发生(标志位是否置位): ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); 这个函数一般使用在中断服务函数的开头判断中断是否发生。 (2)第二个是清除某个中断线上的中断标志位: void EXTI_ClearITPendingBit(uint32_t EXTI_Line); 这个函数一般应用在中断服务函数结束之前,清除中断标志位。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1754 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1613 浏览 1 评论
1053 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1667 浏览 2 评论
1927浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
712浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
562浏览 3评论
584浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
544浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 06:29 , Processed in 0.813421 second(s), Total 75, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号