一、接入红外传感器模块
1、通过下列接线图将对射式红外传感器模块随意选择一个(GPIO)口接入面包板上(这里引脚接入的是P14端口),OLED模块用来显示计次;
2、原理:当物体经过对外式传感器中间经过时,DO就会输出电平跳变的信号,这个跳变信号就会触发PB14号口的中断,这时我们在中断函数里面执行变量++的程序,然后在主循环里面调用OLED显示变量,程序完成。
二、配置外部中断
外部中断(EXTI)基本结构图如下所示:
从GPIO—>AFIO—>EXTI—>NVIC出现的外设模块都要配置好
第一步、打开时钟;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//打开GPIO的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//打开AFIO的时钟
第二部、配置GPIO,端口为输入模式;
这里不过多描述,根据参考手册可知GPIO只能配置浮空输入或带上拉输入或带下拉输入
这里我们选择上拉输入;
代码如下:
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
第三步、配置AFIO,选择要用的GPIO;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
第四步、配置EXTI,
选择边沿触发方式,比如上升沿、下降沿或者双边沿;选择触发相应方式,可以选择中断响应和时间响应(这里选择中断响应);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line14;//配置14号口
EXTI_InitStructure.EXTI_LineCmd=ENABLE;//开启中断
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//设置为中断
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿
EXTI_Init(&EXTI_InitStructure);
第五步、配置NVIC,给中断选择一个合适的优先级
因为前面我们设置的优先级为NVIC_PriorityGroup_2,由下图可以我们可知取值范围为0~3,因为程序的中断只有一个,所以中断优先级的配置也是很随意的,这里我选择1;
代码如下:
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);
第六步、设置中断函数
由于中断函数名字都是固定的,所以中断函数的名字我们参考启动文件,中断函数的名字都是以IRQHandler为结尾的,所以选择下面这个中断函数,看一下EXTI14的标志位是否为1。
中断函数结束后,一定要清除中断标志位,如果要统计中断次数,我们定义一个变量CountSensor_Count,放在中断函数里面,每中断一次就加1,最后再设置一个函数来返回这个变量
代码如下:
/*返回变量函数*/
uint16_t CountSensor_Get(void)
{
return CountSensor_Count;
}
/*设置中断函数*/
void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line14) == SET)
{
/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
{
CountSensor_Count ++;
}
EXTI_ClearITPendingBit(EXTI_Line14);
}
}
最后在main文件里面初始化函数
代码如下:
int main(void)
{
OLED_Init();
CountSensor_Init();
OLED_ShowString(1,1,"Count:");
while(1)
{
OLED_ShowNum(1,7,CountSensor_Get(),5);
}
}