目录
目录
- 目录
- 一、NVIC
-
- 1.中断优先级
- 2.中断优先级分组
- 二、外部中断的一般配置过程
-
- 1.GPIO_Init()
- 2.void EXTIX_Init(void)编写
- 3.void EXTI4_IRQHandler()中断触发函数
- 总结
一、NVIC
1.中断优先级
中断优先级:中断优先级分为抢占优先级和响应优先级;我们配置一个中断的抢占优先级和响应优先级来设置中断的优先级。
抢占优先级:在一个中断正在发生时,另外一个抢占优先级比它高的中断也发生了,那么抢占优先级高的那个中断就可以打断抢占优先级低的那个中断。
响应优先级:如果两个中断的同时发生,他们的抢占优先级相同,但一个的响应优先级高于另外一个,那么响应优先级高的那个中断就先发生。
2.中断优先级分组
我们通过调用函数或者直接操作寄存器来实现中断优先级的分组:
其中第二列是我们可以设置的中断优先级的范围,第三列是我们可以设置的响应优先级的范围。
在固件库中,我们通过调用下面这个函数来确定中断优先级分组:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
这个图片在文件夹 stm32f10x_exti.c
中的 misc.h
这个文件夹可以找到;
二、外部中断的一般配置过程
1.初始化GPIO
2.开启IO口复用时钟
3.设置IO口与中断线的映射关系
4.初始化线上中断(EXTI),设置触发条件
5.配置中断分组(NVIC),并使能中断
6.编写中断服务函数
7.清除中断标志位
1.GPIO_Init()
我这里使用的是红外避障模块,IO口:PB4
void HongWai_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); //根据参数初始化GPIOB.4
}
要注意的点就是:因为红外避障模块遇到障碍物的时候会输出一个高电平,所以配置GPIO的模式的时候要配置成下拉输入。
2.void EXTIX_Init(void)编写
void EXTIX_Init(void)
{
//1.GPIO初始化HongWai_Init();EXTI_InitTypeDef EXTI_InitStructre;NVIC_InitTypeDef NVIC_InitStructre;//2.开启IO口复用时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//3.设置IO口与中断线的映射关系GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource4);//4.初始化线上中断(EXTI),设置触发条件EXTI_InitStructre.EXTI_Line = EXTI_Line4;//配置中断线,和IO口有关EXTI_InitStructre.EXTI_LineCmd = ENABLE;//使能EXTI_InitStructre.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式EXTI_InitStructre.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发EXTI_Init(&EXTI_InitStructre);//5.配置中断分组(NVIC),并使能中断NVIC_InitStructre.NVIC_IRQChannel = EXTI4_IRQn;NVIC_InitStructre.NVIC_IRQChannelCmd = ENABLE;//使能NVIC_InitStructre.NVIC_IRQChannelPreemptionPriority = 2;//中断优先级配置NVIC_InitStructre.NVIC_IRQChannelSubPriority = 2;NVIC_Init(&NVIC_InitStructre);
}
关键代码讲解:
//设置IO口与中断线的映射关系
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource4);
因为我使用的是PB4,所以参数就是GPIO_PortSourceGPIOB
和GPIO_PinSource4
。
//4.初始化线上中断(EXTI),设置触发条件EXTI_InitStructre.EXTI_Line = EXTI_Line4;//配置中断线,和IO口有关EXTI_InitStructre.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发
因为我用的IO是PB4所以中断线就是EXTI_Line4;
EXTI_Trigger_Rising
上升沿触发:当IO的电平由低转到高的时候会触发中断。
//5.配置中断分组(NVIC),并使能中断NVIC_InitStructre.NVIC_IRQChannel = EXTI4_IRQn;
如果io口为1-4:这个参数就是:EXTI1_IRQn ,EXTI2_IRQn,EXTI3_IRQn ,EXTI4_IRQn
如果io为5-9:这个参数就是:EXTI9_5_IRQn
io为10到15:io口为:EXTI15_10_IRQn
3.void EXTI4_IRQHandler()中断触发函数
这个函数名称不可改,和你使用的IO口有关,和上面的NVIC_InitStructre.NVIC_IRQChannel配置是一样的
因为我用的是pb4,所以我编写的中断服务函数就是EXTI4_IRQHandler()
void EXTI4_IRQHandler()
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_4)){
LED0 = !LED0;}EXTI_ClearITPendingBit(EXTI_Line4);
}
我配置的触发方式是上升沿触发,所以进入到中断函数之后是高电平,所以我读取PB4的电平,如果为高电平就执行操作,中间的就可以自己写了。
一定不要忘了:EXTI_ClearITPendingBit(EXTI_Line4);
总结
奉上视频:
你见过会说话的小车吗
最后能达到的效果就是当红外模块检测到障碍物时触发中断,可以在中断服务函数中改为让小车拐弯,这样就实现了一个避障功能。