当前位置: 代码迷 >> 综合 >> STM32智能小车------红外避障+NVIC
  详细解决方案

STM32智能小车------红外避障+NVIC

热度:2   发布时间:2023-11-24 14:56:07.0

目录

目录

  • 目录
  • 一、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_PortSourceGPIOBGPIO_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);

总结

奉上视频:

你见过会说话的小车吗

最后能达到的效果就是当红外模块检测到障碍物时触发中断,可以在中断服务函数中改为让小车拐弯,这样就实现了一个避障功能。