title: 05_2 红外对射式传感器计次
tags:
- STM32
categories: - STM32学习
[[04_2_keil调试工具]]
红外对射式传感器接线图
1.配置中断
配置中断的流程
从GPIO一直到NVIC这一路中出现的外设模块都配置好
- 配置RCC,将涉及到的外设时钟都打开
- 配置GPIO,选择端口为输入模式
- 配置AFIO,选择这一路的GPIO,连接到后面的EXTI
- 配置EXTI,选择边沿触发方式(上升下降双边)、触发响应方式(中断响应或事件响应)
- 配置NVIC,外部中断信号就能进入CPU
注意
- EXTI和NVIC(使用内核的时钟)这两个外设时钟是一直开启着的
- 中断函数的名字是固定的,名字可以参考启动文件,这里的函数名都是固定的
- 中断函数都是无参无返回值的,void func(void)
- 完成中断后记得要清除标记位,最下面那行,然后在这两个红框之间可以放我们想要的函数
AFIO库函数
- AFIO的库函数在
GPIO.h
文件夹中GPIO_PinRemapConfig
用于进行引脚重映射,第一个参数选择重映射的方式,第二个参数是新的状态GPIO_WXTILineConfig
可以配置AFIO的数据选择器,来选择我们想要的中断引脚用这个GPIO_ETH_MediaInterfaceConfig
这个是和以太网有关的,我们这个芯片没有以太网,暂时用不到
EXTI库函数
- 在
exti.h
文件夹下EXTI_DeInit
清除EXTI配置,恢复成上电默认的状态EXTI_Init
初始化EXTIEXTI_GenerateSWInterrupt
用于软件触发外部中断,调用这个函数,参数给一个指定的中断线,就能软件触发一次这个外部中断- 剩下的是库函数的模板函数,在外设运行中,会产生一些状态标志位,这些标志位会放到状态寄存器,当我们需要查看这些标志位的时候,就可以用到这四个函数
- 在主程序中查看标志位,
GetFlagStatus
可以获取指定的标志位是否被置一,ClearFlag
可以对置一的标志位进行清除 - 在中断中需要查看标志位可以用下面量函数,
GetITStatus
获取中断标志位是否被置一,ClearIPendingBit
清楚中断挂起标志位
- 在主程序中查看标志位,
NVIC库函数
由于NVIC是内核外设,所以库函数被分配到杂项misc.c
文件中
NVIC_PriorityGroupConfig
用于中断分组,参数是中断分组的方式- pre-emption priority 先占优先级-抢占优先级
- subpriority 从占优先级- 响应优先级
NVIC_SetVectorTable
设置中断向量表NVIC_SystemLPConfig
系统低功耗配置,一般物联网会有要求
代码
int16_t CountSensor_Count; //在此处定义一个全局变量供给在中断中使用
void CountSensor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIO的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //开启AFIO的时钟
GPIO_InitTypeDef GPIO_InitStructure; //初始化GPIO
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);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14); //配置AFIO
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line14; //指定需要跳转的中断线
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //指定中断线的新状态
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //指定选择的中断线的模式,
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //选择触发模式
EXTI_Init(&EXTI_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC是核内外设,被分配到,misc.c文件中
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //指定中断通道是开启或关闭,指定开启EXTI15~10开启
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定中断通道是使能还是失能
//我们选择的分组是组2,所以对应优先级的取值范围是0~3 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)
{
CountSensor_Count ++;
}
EXTI_ClearITPendingBit(EXTI_Line14);
}
}
不同的触发模式对现象的影响
- 选择上升沿触发
- 程序会在挡片拿走的时候计次
- 选择下降沿触发
- 程序会在挡片落下的时候计次
- 选择双边沿触发
- 程序会在挡片落下和拿走的时候都计次,也就是变化两次