stm32红外对射计次
目前这个程序有问题,遮挡然后移开count加了不止一次。可能是由于硬件抖动原因。

// main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"

int main(void)
{
    OLED_Init();
    Count_Sensor_Init();
    while(1)
    {
        OLED_ShowNum(1, 1, Get_Count_Sensor_Count(), 5);
    }
}
// CountSensor.c

#include "stm32f10x.h"                  // Device header
#include "delay.h"

uint16_t Count_Sensor_Count = 0;

uint16_t Get_Count_Sensor_Count(void)
{
    return Count_Sensor_Count;
}

void Count_Sensor_Init(void)
{
/*
依次配置好:
1. RCC时钟打开 -- GPIO和AFIO,
2. 一路GPIO,
3. AFIO -- 把选择的一路GPIO接到(映射到)EXTI的0-15输入脚,
4. EXTI -- 选择边沿触发方式(上升沿,下降沿,双边沿),选择中断响应方式(中断响应,事件响应),
5. NVIC -- 为这个中断选择合适优先级。
*/
    // 1.
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    
    // 2.
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 下拉输入, input down
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    // 3. (GPIOB PB0) -> AFIO0 -> (EXTI)
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0); 
    
    // 4.
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line0; // EXTI线0
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
    // 我的模块是遮住输出1,空闲输出0,要想检测物体离开,应该是下降沿触发。
    EXTI_Init(&EXTI_InitStructure);
    
    // 5.
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 2抢占+2响应
    // 注:上面这个函数在整个程序内只需要执行一次,为了思路清晰,模块化编程,
    // 故把它放在这里。如果程序在其他地方也要写这个函数,务必参数要相一致。
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStructure);
}

void EXTI0_IRQHandler(void)
{
// 中断函数都是固定的函数名在启动文件startup_.....s文件里面找,
// 中断函数都是无参数无返回值的。
// 中断函数由硬件系统自动调用,不必写在头文件里。

    /* 如果是中断:EXTI15_10_IRQHandler(),10到15号都能触发同一个中断,
       则应该判断具体是由哪个线路申请的中断,如下if判断是否是EXTI线14申请的。
       此处只有EXTI线0能申请EXTI0_IRQHandler(),故不用判断,不,还是用吧。
    */
    
    if(EXTI_GetITStatus(EXTI_Line0) == SET)
    {
        Count_Sensor_Count++;
        EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志位
    }
}