STM32__红外避障模块的使用

目录

一、红外避障模块 概述

二、直接读取OUT引脚电平

三、使用中断方式触发


一、红外避障模块 概述

引脚解释:

VCC接3.3V 或 5.0V
GND接开发板的GND
OUT数字量输出(0或1); 低电平时表示前方有障碍 ; 通过可调电阻调整检测距离 

产品特点:

工作电压推荐3.3V, 也可以5V
模块功耗23mA~40mA
检测距离<=30cm ; 通过可调电阻调整检测距离 
指示灯电压灯 + 障碍指示灯

模块描述:

1、可以广泛应用于机器人避障、避障小车、流水线计数、黑白线循迹 等众多场合。

2、采用3.3V 或 5V 直流电源对模块进行供电。当电源接通时,电源指示灯点亮;

3、该传感器模块对环境光线适应能力强,其具有一对红外线发射与接收管,发射管发射出一定频率的红外线,当检测方向遇到障碍物(反射面)时,红外线反射回来被接收管接收,经过比较器电路处理之后,绿色指示灯会亮起,同时OUT端口持续输出低电平信号(0);

4、检测距离2~30cm,检测角度35°; 检测距离可以通过电位器进行调节,顺时针调电位器,检测距离增加;逆时针调电位器,检测距离减少。

5、传感器是主动红外线反射探测, 因此目标的反射率和形状是探测距离的关键。其中黑色探测距离最小, 白色最大; 小面积物体距离小,大面积距离大。

6、输出端口OUT可直接与单片机IO口连接,使用代码读取OUT电平,或使用中断触发的方式;  另外, OUT引脚也可以直接驱动一个5V继电器;

7、使用前,建议先用螺丝刀调节好需要的触发距离 (绿灯亮),再接入单片机进行开发调试。

8、具有3mm的螺丝孔,便于固定、安装;


二、程序直接读取OUT引脚电平

OUT接口在闲时(没有发现障碍物),是持续的高电平状态;高电平的电压值是供电电压值;

当发现障碍物时,OUT接口将持续地输出低电平,直到障碍物消失时再输出高电平;

因此,我们可以在STM32工程中,直接用代码读取OUT接口的电平,即可知道是否遇到障碍物。

  • 这里以OUT接口,连接PC12引脚为示例;(哪个引脚都可以,只要是空闲的引脚即可)
  • PC12引脚工作模式,无需初始化、设置。因为读电平,不管哪种模式状态下都可以直接读。

在main的while中,编写以下代码即可:

HAL_Delay(500);                                            // 延时间隔

uint8_t state = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_12);      // 读取OUT引脚电平; 只是读引脚电平,用哪个引脚都可以,无需提前初始化
if (state == 0)                                            // 判断 OUT 引脚是否是低电平(闲时高电平,遇到障碍物时持续输出低电平)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);  // 点亮蓝色LED; 引脚PB2, 低电平通路点亮;
    printf("发现障碍物!\r\n");                            // 打印提示信息; printf需要预先使能UART1,并重定向到UART1输出
}
else
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);    // 熄灭蓝色LED; 引脚PB2, 高电平断路熄灭;
}

完成后,位置如下图:

上面的代码,当PC12为低电平时(遇到障碍物):亮灯、printf输出提示信息;


三、使用中断方式触发

上面的读取方式,操作简单、容易理解。

但这种方式有一个潜在隐患:处理可能不及时。

如,当小车高速开跑中,遇到了障碍物,但程序却正在运行其它功能的代码, ......。

小车翻车没啥事,但如果用在工业现场,如电机、导轨等, 那就严重了!

我们可以使用中断触发的方式,发现障碍物,立即进入执行处理!

下面,还是以OUT接口连接PC12作示例,示范CubeMX的中断触发配置、编写回调函数代码。

1、配置引脚的工作模式

  • 点击需要使用的引脚,选择:GPIO_EXTI,即 外部中断模式

2、配置触发方式

  • 根据OUT接口的工作特点,配置为: Interrupt  Falling ,即下降沿触发中断;
  • 设置为上拉,即 闲时引脚电平保持在高电平状态;

3、使能中断线

  • 在 NVIC 中断控制器页面中,打勾对应的中断线,令中断控制器能够响应该中断线,从而使芯片能够接收并处理引脚的电平跳变事件。

引脚编号与中断线对应的关系是:

GPIO_PIN_0EXTI_Line0
GPIO_PIN_1EXTI_Line
GPIO_PIN_2EXTI_Line
GPIO_PIN_3EXTI_Line
GPIO_PIN_4EXTI_Line
GPIO_PIN_5    至  GPIO_PIN_9    共用一个中断线EXTI_Line[9:5]
GPIO_PIN_10  至  GPIO_PIN_15  共用一个中断线EXTI_LineEXTI_Line[15:10]

至此,引脚的中断触发,配置完成,重新生成。

4、编写中断回调函数

CubeMX配置上述中断后,将自动生成底层的初始化、中断服务函数等代码。

当引脚发生了配置中的电平跳变时,将触发硬件自动调用程序里的中断服务函数,继而调用程序里的EXTI中断回调函数:HAL_GPIO_EXTI_Callback ( );

这个回调函数在CubeMX生成时,在stm32xx_hal_gpio.c中已生成了弱定义;

我们在适合的、喜欢的位置,自行重新编写HAL_GPIO_EXTI_Callback函数,即能被中断函数调用到。

我们在main.c的下方,/* USER CODE BEGIN 4 */之下,编写此回调函数:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_12)                               // 由PC12触发
    {
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);  // 点亮蓝色LED; 引脚PB2, 低电平通路点亮;
        printf("发现障碍物!\r\n");                            // 打印提示信息; printf需要预先使能UART1,并重定向到UART1输出
    }

}

完成后,位置如下图:

如上,即可实现遇到障碍物时,实时地执行处理。

这里的亮灯、printf,只是示范,你可以替换成需要的执行,如刹车、关闭设备电源等。

5、多次触发的解决思路

当使用中断触发,可能会有一个使用上明显的bug:连续多次触发!

这个bug的产生,是OUT接口输出低电平信号过程中的振铃现象所导致的。

测试了三个不同店家的红外避障模块,有两家模块存在多次触发现象。

物理解决方案:

        在 OUT接口与GND间,并联一个1uF左右的小电容(1uF只是建议,具体得根据现场而定);

代码解决方案:

        在中断回调函数里,增加5ms延时,即HAL_Delay(10ms),让程序刻意“错过”振铃导致的多次触发。这种方式有点像按键的消抖处理。但是,不建议使用这种方式,因为在中断里延时死等,有可能导致其它通信的中断无法及时执行,数据丢包! 如果确定要使用这种方式(在中断里使用HAL_Delay),  注意会产生中断嵌套冲突。需要在CubeMX里修改NVIC的Time base响应优先级,默认是15 (最低),把它修改为0 (最高),然后,把引脚中断线的优先级,默认是0 (最高),修改为大于0的值,如1、6等。这样处理后,在EXTI的中断回调函数里才能使用HAL_Delay函数。

操作如下图:


如有错漏,望指正,将及时更新修改~~~

<think>我们正在使用STM32标准(而非HAL)来配置和使用红外避障模块红外避障模块通常输出数字信号(高电平表示无障碍,低电平表示有障碍)或模拟信号(通过电压值判断距离)。这里我们假设使用的是数字输出的红外避障模块。步骤概述: 1.硬件连接:确定红外避障模块的输出引脚连接到STM32的哪个GPIO口,以及模块的供电(VCC和GND)。2.GPIO配置:将该GPIO配置为输入模式(上拉或浮空输入,根据模块输出特性决定)。3.读取GPIO状态:在程序中读取该GPIO的电平状态,判断是否有障碍物。 详细步骤:###1.硬件连接假设红外避障模块的OUT引脚连接到了STM32的PA0引脚。模块的VCC接3.3V,GND接GND。###2.GPIO配置在标准中,我们需要配置GPIO为输入模式。由于模块输出在无障碍时通常为高电平,有障碍时为低电平,并且模块内部可能已经集成了上拉电阻,如果没有,我们可以在STM32内部配置上拉电阻(或者外部上拉)。这里我们配置为带上拉电阻的输入模式。```c#include "stm32f10x.h"void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;//开启GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//配置PA0为输入模式,上拉GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU; //上拉输入GPIO_Init(GPIOA,&GPIO_InitStructure); }``` ###3.读取GPIO状态在主循环中,我们可以读取PA0的状态,根据电平判断障碍物。 ```cint main(void){GPIO_Configuration();//初始化GPIOwhile(1){//读取PA0引脚状态if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)== Bit_RESET){//低电平,表示检测到障碍物//执行相应动作,例如点亮LED或发送信号}else{//高电平,无障碍物}//可以加入延时,防止过于频繁读取Delay_ms(100); //需要自己实现延时函数或使用系统滴答} }``` ###4.使用中断方式(可选) 如果需要高效检测,可以使用外部中断。将PA0配置为外部中断线0(因为PA0对应EXTI0)。 ```cvoidEXTI_Configuration(void){EXTI_InitTypeDefEXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//配置GPIO(同上)并开启AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//将PA0连接到EXTI0GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);//配置EXTI0EXTI_InitStructure.EXTI_Line= EXTI_Line0;EXTI_InitStructure.EXTI_Mode= EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;//下降沿触发(从高电平变为低电平,检测到障碍)//或者使用上升沿触发(EXTI_Trigger_Rising)当障碍物离开时触发//或者双边沿(EXTI_Trigger_Rising_Falling)EXTI_InitStructure.EXTI_LineCmd= ENABLE;EXTI_Init(&EXTI_InitStructure);//配置NVICNVIC_InitStructure.NVIC_IRQChannel =EXTI0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x0F;NVIC_InitStructure.NVIC_IRQChannelSubPriority =0x0F;NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;NVIC_Init(&NVIC_InitStructure);} //中断服务函数voidEXTI0_IRQHandler(void) {if(EXTI_GetITStatus(EXTI_Line0)!= RESET){//处理障碍物检测事件//例如,设置标志位或直接处理//清除中断标志EXTI_ClearITPendingBit(EXTI_Line0);} }``` 然后在主函数中初始化外部中断,并在主循环中处理标志位或直接在中断服务函数中处理。###注意事项-根据实际模块的电气特性选择输入模式(上拉、下拉或浮空)。如果模块输出在无信号时处于浮空状态,建议使用上拉或下拉以避免干扰。 -如果模块输出是开漏结构,则必须使用上拉电阻(内部或外部)。以上是基于STM32标准使用数字输出红外避障模块的基本方法。对于模拟输出的红外避障模块,则需要使用ADC进行电压采集,然后根据电压值判断距离。 §§相关问题§§1.如何判断红外避障模块是数字输出还是模拟输出?2.如何配置STM32的ADC来读取模拟红外避障模块? 3.红外避障模块的检测距离如何调整?4.多个红外避障模块如何同时使用?</think>### 在STM32标准中配置和使用红外避障模块 #### 一、硬件连接(以STM32F103为例) 1. **模块引脚**: - VCC → 3.3V - GND → GND - OUT → GPIO引脚(如PA0) 2. **工作逻辑**: - 无障碍时:OUT输出**高电平**(3.3V) - 有障碍时:OUT输出**低电平**(0V) #### 二、软件配置步骤 ##### 1. 初始化GPIO(输入模式) ```c #include "stm32f10x.h" void IR_Obstacle_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; // 开启GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置PA0为浮空输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入模式 GPIO_Init(GPIOA, &GPIO_InitStructure); } ``` ##### 2. 读取障碍状态 ```c #define OBSTACLE_DETECTED 0 // 低电平表示有障碍 #define NO_OBSTACLE 1 // 高电平表示无障碍 uint8_t Check_Obstacle(void) { if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET) { return OBSTACLE_DETECTED; // 检测到障碍 } return NO_OBSTACLE; // 无障碍 } ``` ##### 3. 主循环示例 ```c int main(void) { IR_Obstacle_Init(); // 初始化红外模块 while (1) { if (Check_Obstacle() == OBSTACLE_DETECTED) { // 执行避障动作(如停止电机) // GPIO_SetBits(GPIOC, GPIO_Pin_13); // 点亮LED报警 } else { // 正常行进 // GPIO_ResetBits(GPIOC, GPIO_Pin_13); } Delay_ms(50); // 适当延时防抖动 } } ``` #### 三、关键注意事项 1. **消抖处理**: ```c // 连续检测3次确认障碍 uint8_t Confirm_Obstacle(void) { uint8_t count = 0; for (int i = 0; i < 3; i++) { if (Check_Obstacle() == OBSTACLE_DETECTED) count++; Delay_ms(10); } return (count >= 2) ? OBSTACLE_DETECTED : NO_OBSTACLE; } ``` 2. **中断模式配置**(可选): ```c void EXTI0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line0) != RESET) { // 处理障碍中断 EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志 } } ``` #### 四、调试技巧 1. **串口输出状态**: ```c printf("Obstacle: %s\n", Check_Obstacle() ? "CLEAR" : "BLOCKED"); ``` 2. **LED指示**: - 检测到障碍时点亮LED(如PC13) #### 五、常见问题解决 1. **无响应**: - 检查VCC/GND是否接反 - 用万用表测量OUT引脚电压变化 - 确认GPIO模式配置为`GPIO_Mode_IN_FLOATING` 2. **误触发**: - 增加硬件滤波电容(0.1μF并联在OUT-GND) - 调整模块上的灵敏度电位器(若有) > 参考配置依据:STM32标准的GPIO输入模式配置要求[^1],红外模块的电气特性[^2],以及实际消抖处理经验[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值