#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"
int main(void)
{
OLED_Init();
CountSensor_Init();
OLED_ShowString(1, 1, "Count:");
while (1)
{
OLED_ShowNum(1, 7, CountSensor_Get(), 5);
}
}
首先是主函数,进行调用函数以及初始化工作,利用OLED显示中断结果。
下面主要针对CountSensor_Init()进行分析。
#include "stm32f10x.h" // Device header
uint16_t CountSensor_Count;
void CountSensor_Init(void)
{
//开启外设的时钟,外设分别有GPIO、AFIO、EXTI、NVIC,按照道理来说都需要开启时钟函数,但是EXTI、NVIC位内核控制因此无需开启时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//对GPIO进行初始化
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//设置GPIO的输入输出模式,这里设置的位GPIO的输入上拉模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;//指定14号引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//引脚输出速度
GPIO_Init(GPIOB, &GPIO_InitStructure);
//关联引脚与EXTI中断线
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);
//设定中断优先级分组4位,抢断优先级,响应优先级,值越小越优先
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//值得注意的是,应该是为了节省引脚,将10-15号融合在一个引脚
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
NVIC_Init(&NVIC_InitStructure);
}
//获取中断函数中变量值
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)//判断GPIO输入口是否是低电平
{
CountSensor_Count ++;
}
EXTI_ClearITPendingBit(EXTI_Line14);//必须要进行清楚,不然会一直响应
}
}