问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32对射式红外传感器配置详解

创作时间:
作者:
@小白创作中心

STM32对射式红外传感器配置详解

引用
CSDN
1.
https://m.blog.csdn.net/2401_84378523/article/details/145380315

本文将详细介绍如何使用STM32F103开发板配置对射式红外传感器。文章将从硬件连接、软件配置到实际应用等多个方面进行讲解,帮助读者掌握这一技术。

对射式红外传感器

对射式红外传感器由一个红外发光二极管和NPN光电三极管组成,具有M3固定安装孔。传感器有输出状态指示灯,当输出高电平时灯灭,输出低电平时灯亮。当有遮挡时,传感器输出高电平;无遮挡时,输出低电平。传感器使用3.3-5VDC宽电压LM393比较器输出,信号干净,波形好,驱动能力强,超过15mA。输出形式为数字开关量输出(0和1)。这种传感器广泛应用于电机转速检测、脉冲计数、位置限位等领域。

引脚说明

  • VCC:接电源正极3.3V-5V
  • GND:接电源负极
  • DO:TTL开关信号输出
  • AO:此模块不起作用

操作说明

  1. 接好VCC和GND,模块电源指示灯会亮
  2. 模块槽中无遮挡时,接收管导通,模块DO输出低电平,开关指示灯亮;遮挡时,DO输出高电平,开关指示灯灭。
  3. 模块DO可与继电器相连,组成限位开关等功能,也可以与有源蜂鸣器模块相连,组成报警器。
  4. DO输出接口可以与单片机IO口直接相连,一般接外部中断,检测传感器是否有遮档,如用电机码盘则可检测电机的转速。

工作原理

测距离

测速传感器输出为脉冲信号,一个脉冲中断一次。红外射线导通的时候是低电平,所以我们设置中断为低电平触发模式。一般码盘上有整数格子,无论是多少格其实原理一样,例如10格码盘,也就是有10个空格子,电机转一圈后便是射线导通10次,外部低电平触发10次。安装上面的思路,我们的测速传感器就可以发挥出效果了,我们知道一圈就有10个中断,于是我们计算中断次数,得到的总次数除于10也就是电机转动次数了,然后按照轮子的周长,计算轮子一圈是多长,就可以推算出小车已经跑多远了。

测速度

按照测距离的思路,我们用一个MCU定时器计算,1秒内接收多少个外部中断,例如一秒内接收了20个外部中断,我们就可以判断小车速度为1秒小车轮子转两圈,然后再计算出小车轮子的周长,就可得知小车1秒行驶的速度。

代码配置

代码配置主要包括GPIO配置、中断线与GPIO引脚的连接、EXTI配置、NVIC配置等步骤。

EXTI函数解析

  • void EXTI_DeInit(void);:调用它,就可以把EXTI的配置都清除,恢复成上电的默认的状态
  • void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);:调用这个函数,就可以根据这个结构体里的参数配置EXTI外设,初始化EXTI要用到这个函数
  • void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);:这个函数可以把参数传递的结构体变量赋一个默认值
  • void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);:这个函数是用来软件触发外部中断的,调用这个函数,参数给一个指定的中断线,就能软件触发一次外部中断

在外设运行的过程中,会产生一些状态标志位。比如外部中断来了,会有一个挂起的寄存器置了一个标志位,对于其他外设,如串口收到数据,会置标志位,定时器时间到也会置标志位,这些标志位都是放在状态寄存器的,当程序想要看这些标志位时,就会用到下面四个函数:

  • FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);:可以获取指定的标志位是否被置1
  • void EXTI_ClearFlag(uint32_t EXTI_Line);:可以对置1的标志位进行清除
  • ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);:在中断函数里,如果你想查看标志位和清除标志位,用这个函数可以获取中断标志位是否被置1
  • void EXTI_ClearITPendingBit(uint32_t EXTI_Line);:在中断函数里,如果你想查看标志位和清除标志位,用这个函数可以清除中断挂起标志位

总结:如果想要在主程序里查看和清除标志位,就用上面两个函数。
如果想要在中断函数里查看和清除标志位,就用下面两个函数。

NVIC函数解析

  • void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);:这个函数是用来中断分组的,参数是中断分组的方式
  • void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);:根据结构体里面指定的参数初始化NVIC
  • void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);:设置中断向量表
  • void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);:系统低功耗配置

初始化函数

void CountSensor_Init(void)
{
    //------------------------定义结构体变量-----------------------------------
    GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO结构体变量
    EXTI_InitTypeDef EXTI_InitStructure; //定义EXTI结构体变量
    NVIC_InitTypeDef NVIC_InitStructure; //定义NVIC结构体变量

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开启GPIO的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO的时钟

    //---------------------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初始化

    //---------------------GPIO配置--------------------------------------
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14); //将中断线与GPIO引脚连接

    //---------------------EXTI配置--------------------------------------
    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);

    //---------------------EXTI配置--------------------------------------
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组,这里放到模块函数里了,一般情况放在主函数第一行(如上一章按键中断)

    //---------------------NVIC配置--------------------------------------
    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);

    //---------------------NVIC配置--------------------------------------
}

中断函数

uint16_t CountSensor_Count;

//中断函数
void EXTI15_10_IRQHandler(void)
{
    //判断中断标志位是否为 1 EXTI_GetITStatus的返回值为 SET(1)  或者RESET(0)
    if(EXTI_GetITStatus(EXTI_Line14) == SET)
    {
        //判断电平,以免发生抖动
        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14) == 0)
        {
            CountSensor_Count++;
        }
        //中断标志位置1,程序就会跳转到中断函数,
        //如果不清除中断标志位,就会一直申请中断,这样就会不断响应中断,执行中断函数,
        //程序就会卡死在中断函数里,所以每次中断程序结束后,都应该清除一下中断标志位
        EXTI_ClearITPendingBit(EXTI_Line14);
    }
}

//返回值
uint16_t CountSensor_Get(void)
{
    return CountSensor_Count;
}

主函数

功能:挡住传感器模块槽,OLDE显示数字变化+1

#include "CountSensor.h"

int main(void)
{
    LED_Init();
    OLED_Init();
    CountSensor_Init();
    OLED_ShowString(1, 1, "Count:");
    while(1)
    {
        OLED_ShowNum(1, 7, CountSensor_Get(),5);
    }
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号