提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
详细记述了stm32标准库的中断函数解析
提示:以下是本篇文章正文内容,下面案例可供参考
一、外部中断的引用
1.GPIO引用
一个小常识
这张图片来自stm32中文手册有关寄存器的介绍
从图片中可以看到同等数字中断的GPIO引脚用的是同一个线路
也就是说选了PA0作为器件A的中断触发引脚,就不能使用PB0作为器件B的中断触发引脚
来看官方对EXTI的输入方式选用
我们选上拉
直接放代码
GPIO_InitTypeDef GPIO_InitStructure;
// 使能GPIOB
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
2.AFIO配置
首先看gpio.h的库函数
这个函数的作用是复位AFIO,给他归零
这个函数的作用的选取中断线,这一篇我们只用到了这个(暂时只明白这个哈哈)
代码写起来是这样的
//使能AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource12);
EXTI_InitTypeDef exit;//定义结构体名字,看个人习惯
exit.EXTI_Line=EXTI_Line12;
exit.EXTI_LineCmd=ENABLE;
exit.EXTI_Mode=EXTI_Mode_Interrupt;
exit.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Init(&exit);
从第二句开始分析
右键追踪可以看到这个函数的注释
第一个参数是选用的GPIO口,第二个参数是选的Pin
按照他给的格式改一下x的值就好了
结构体的第一个参数EXTI_Line
右键过来可以看到注释,意思是说可以写@后面这个参数
再次追踪就能看见可以写的参数
我们用的引脚是12,就选EXTI_Line12
第二个参数是使能参数,都用中断了肯定使能啊【手动狗头】
第三个参数:手动追踪过来可以看到这两个参数
第一是中断,第二个是事件
中断一定要有对应的中断函数去执行
事件不一定要有对应的执行函数,只是得知这件事情
第四个参数:触发方式的选择
第一个上拉
第二个下拉
第三个上下拉
最后的就是初始化结构体,在exti.h文件里可以找到
3.NVIC的配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef nvic;
nvic.NVIC_IRQChannel=EXTI15_10_IRQn;
nvic.NVIC_IRQChannelCmd=ENABLE;
nvic.NVIC_IRQChannelPreemptionPriority=1;
nvic.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&nvic);
第一句是中断的优先级分组【优先级越小,优先级越大】-_-
一般选第二个分组就够了NVIC_PriorityGroup_2
第一个参数是选择路线
我用的是最小系统板,选中间的MD
12在10~15之间
选EXTI15_10_IRQn
第二个参数:打开使能 ENABLE
第三个参数和第四个参数对应的是抢占优先级和响应优先级
现在只有这一个中断随便写写就好了
4.中断函数
查看exti.h文件
第一个是软件触发中断
第二个函数是判断中断的标志位,在主函数中使用
第三个是清除中断的标志位,在主函数中使用
第四个函数是判断中断的标志位,在函数中使用
第五个是清除中断的标志位,在函数中使用
查看启动文件,这是中断的所有函数名字
我们选用EXTI15_10_IRQHandler
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line12)==SET)
{
//清除标志位
EXTI_ClearITPendingBit(EXTI_Line12);
}
二、完整代码
中断函数自己写
#include "stm32f10x.h"
#include "exit.h"
void contrl_exti(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// ʹÄÜGPIOBʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//ʹÄÜAFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//ÅäÖÃGPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//ÅäÖÃAFIO
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource12);
EXTI_InitTypeDef exit;
exit.EXTI_Line=EXTI_Line12;
exit.EXTI_LineCmd=ENABLE;//¿ªÆôÖжÏ
exit.EXTI_Mode=EXTI_Mode_Interrupt;//ÖжÏģʽ
exit.EXTI_Trigger=EXTI_Trigger_Falling;//Ͻµ´¥·¢
EXTI_Init(&exit);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef nvic;
nvic.NVIC_IRQChannel=EXTI15_10_IRQn;
nvic.NVIC_IRQChannelCmd=ENABLE;
nvic.NVIC_IRQChannelPreemptionPriority=1;
nvic.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&nvic);
}
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line12)==SET)
{
//ÖжÏ
EXTI_ClearITPendingBit(EXTI_Line12);
}
}
完结撒花!