今天实现了火焰传感器+stm32+OLED的串联。
火焰传感器来检测火焰出现的次数,然后触发中断,在中断里计数,最后显示次数在OLED上。技术主要难在中断的配置上。下面我要记录我对中断的经验。
一、EXTI中断理解
上面这是对EXTI外部中断的比较详细的解释。
以通俗的语言来说,就是当EXTI检测指定GPIO口时,当发现电平跳动后,立马触发中断,讲CPU正在执行的程序停止,来进行中断程序。
其中相同的pin不能同时触发中断的意思,我举个例子就记住了,比如:PA0和PB0不能同时触发中断,PA1和PB0可以。
事件响应主要是发生中断后可以不通知cpu,直接使其他外设起作用。跳过cpu。
二、EXTI基本结构
三、中断代码配置及解析
void CountSensor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//启动四个时钟外设,APB2,AFTO,EXTI,NVIc.但是NVIc是内核外设不需要启动,一直打开。EXTT也不需要。
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//当不知道选什么时,可以看stm32xx参考手册
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line = EXTI_Line14;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
}
第一步:启动时钟外设,因为我选择EXTI监控的引脚是PB14,所以启动APB2时钟。AFIO时钟是任何设置都要启动的。NVIc是内核外设不需要启动,一直打开。EXTT也不需要。
第二步:将GPIO口初始化(GPIO_Init)
第三步:设置IO口与中断线的映射关系(GPIO_EXTILineConfig)
第四步:EXIT初始化
第五步:NVIC初始化
这样完成后则将中断初始化完成了。
四、中断函数编写
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line14) == SET){
EXTI_ClearITPendingBit(EXTI_Line14);
}
/*开始前先判断是不是预先设定的中断线路发生了中断,是的话则进入中断程序,
并且结束后一定要清除中断标志位。否则会一直在中断程序里执行*/
}
这里需要注意的有:
1.中断函数定义一定要定义成你所设置的中断线。可以在启动文件里找到。
2.当得到电平状态后,一定要清除中断标志位。
3.最后在中间写中断需要执行的操作就行了。