基于STM32对射式红外传感器计次
一,实验目的:初步理解中断
二,实验内容:对射式红外传感器
接线:VCC、GND分别接电源的正负极,DO数字输出端,任意选择一个GPIO口接上就行(以PB14口为例,当我们的挡光片或者编码盘在这个对射式红外传感器中间经过时,DO就会输出电平跳变信号,然后这个电平跳变信号触发STM32 PB14口的中断,在中断函数里,执行变量++的程序,然后主循环里调用OLED显示这个变量)
外部中断配置:
把从GPIO到NVIC这一路中出现的外设模块都配置好。
第一步,配置RCC(把涉及的外设时钟都打开,GPIOB是APB2的外设,AFIO也是APB2的外设,EXTI和NVIC两个外设一直是打开的);
第二步,配置GPIO,选择我们得端口为输入模式;
第三步,配置AFIO,AFIO没有专门的库函数文件,它的库函数是和GPIO在一个文件里的,所以找GPIO.h文件——配置AFIO外部中断引脚选择用GPIO_EXTILineConfig函数——跳到定义看参数(到这里,AFIO外部中断引脚选择配置就完成了);
第四步,配置EXTI,与GPIO类似,选择边沿触发方式,比如上升沿/下降沿或者双边沿,还有选择触发响应方式(中断响应和事件响应);
第五步,配置NVIC,打开misc.h查看定义,这里需要用到的是前两个。给我们这个中断选择一个合适的优先级;最后通过NVIC,外部中断信号就能进入CPU了。
代码:
void CountSensor_Init(void)
{
//结构体定义写在最前面
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//配置GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//配置AFIO
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
EXTI_InitStructure.EXTI_Line = EXTI_Line14; //指定配置的中断线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //指定外部中断线的模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //指定触发信号的有效边沿
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //指定选择中断线的新状态
EXTI_Init(&EXTI_InitStructure);
//配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组 参数是中断分组的方式
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//指定中断通道来开启或关闭
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE ;//指定中断通道是使能还是失能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1 ;//指定抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1 ;//指定响应优先级
NVIC_Init(&NVIC_InitStructure);
}
中断函数:
外部中断的信号从GPIO->AFIO->EXTI->NVIC->CPU,这样才能让CPU由主程序跳到中断程序执行。
中断函数放中断程序:打开启动文件——找到需要的中断函数名,调用这个函数,就可以配置AFIO的数据选择器,来选择我们想要的中断引脚。
在中断函数里,一般都是先进行一个中断标志位的判断(确保是想要的中断源触发这个函数),exti.h——复制EXTI_GetITStatus——跳转定义——第一个参数EXTU_Linex——判断EXTU_Line14标志位是否为1——返回值是Set(1)或者Reset(0)
用一个数字来统计中断触发次数:在本模块上定义一个变量,uint16_t CountSensor_Count——在中断函数里CountSensor_Count++——用一个函数CountSensor_Get返回CountSensor_Count
代码:
#include "stm32f10x.h" // Device header
uint16_t CountSensor_Count;
uint16_t CountSensor_Get(void)
{
return CountSensor_Count;
}
void EXTI15_10_IRQHandler (void)//中断函数不用声明 因为是自动执行的
{
if(EXTI_GetITStatus(EXTI_Line14) == SET)
{
CountSensor_Count ++;
EXTI_ClearITPendingBit(EXTI_Line14);//清除中断标志位
}
}
三,实验结果:在这里就不展示了
四,实验总结:中断函数不在主程序中,进行中断函数时主程序先暂停执行,中断函数执行完以后才会重新执行主程序。外部中断的信号从GPIO->AFIO->EXTI->NVIC->CPU,这样才能让CPU由主程序跳到中断程序执行。