【STM32】标准库与HAL库对照学习教程外设篇--红外避障传感器


STM32全部教程【STM32】标准库与HAL库对照学习系列教程大全

一、前言

本篇介绍如何使用STM32控制红外传感器,方法有软件控制与IO口中断控制,本篇使用IO口中断的形式检测红外传感器的信号并控制LED灯闪烁

关于LED的使用与外部中断的使用与配置在:
【STM32】标准库与HAL库对照学习教程三–使用库函数配置GPIO点亮LED灯
【STM32】标准库与HAL库对照学习教程五–外部中断详讲与配置
以有详细说明,因此在本篇文章中,只讲程序,不会讲具体工程的配置。

二、准备工作

  • STM32开发板(我用的是普中的STM32F103ZE的Z200系列)
  • STM32cubemx软件、keil5(MDK)
  • 红外避障传感器

三、红外避障传感器

1、传感器原理说明

红外避障传感器的型号有很多种,但原理上大多都相同,具体由一对红外光线发射管与红外光线接收管、传感器电路组成,引脚上有VCC、GND、OUT三个引脚。

工作原理是红外光线发射管发射红外光线,红外光线接收管接收红外光线,当没有接收到返回的红外光线时,OUT引脚输出高电平,当接收到返回的红外光线时,OUT引脚输出低电平
在这里插入图片描述
上图为我们经常使用的传感器图

2、传感器特性

  • 工作电压:3.3V-5V
  • 工作电流:≥20mA
  • 工作温度:-10℃到+50℃
  • 检测距离:2-10cm
  • 输出信号:接收到光线输出低电平,没有接收到光线输出高电平

四、标准库使用红外传感器

1、实验程序

infrared.h

#ifndef INFRARED_H_
#define INFRARED_H_



#include "stm32f10x.h"

/************引脚重定义************/
#define Infrared_PIN GPIO_Pin_6  
#define Infrared_RCC RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO
#define Infrared_Port GPIOC

extern u8 Infrared_LED0;  

void Infrared_Init(void); //红外传感器初始化函数


#endif

infrared.c

#include "infrared.h"



/*************************************************
*函数名:    Infrared_Init
*函数功能:  红外传感器初始化函数
*输入:      无
*返回值:    无
**************************************************/
void Infrared_Init()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	EXTI_InitTypeDef EXTI_InitStruct;
	
	RCC_APB2PeriphClockCmd(Infrared_RCC, ENABLE); //打开引脚时钟与映射时钟
	
	GPIO_InitStruct.GPIO_Pin = Infrared_PIN;  //接收信号引脚
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;  //下拉输入
	GPIO_Init(Infrared_Port, &GPIO_InitStruct); //引脚初始化
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource6); //打开infrared引脚的相应通道
	
	NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;  //中断通道
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;  //抢占式优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;  //响应式优先级
	NVIC_Init(&NVIC_InitStruct);  //中断通道初始化
	
	EXTI_InitStruct.EXTI_Line = EXTI_Line6;  //中断通道
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;  //中断模式
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;  //中断使能
	EXTI_Init(&EXTI_InitStruct);  //中断初始化
	
}

u8 Infrared_LED0 = 0;  //LED闪烁信号标志
/*************************************************
*函数名:     EXTI9_5_IRQHandler
*函数功能:   外部中断函数
*输入:       无  
*返回值:     无
**************************************************/
void EXTI9_5_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line6))
	{
		Infrared_LED0 = 1;
		EXTI_ClearITPendingBit(EXTI_Line6);
	}
}

main.c

#include "LED.h"
#include "Delay.h"
#include "System.h"
#include "infrared.h"


/*************************************************
*函数名:    main
*函数功能: 主函数
*输入:     无  
*返回值:   无
**************************************************/
int main()
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SysTick_Init(72);
	LED_Init();
	Infrared_Init();
	while(1)
	{
			if(Infrared_LED0 == 1)  //感知到红外信号
			{
				LED_0 = 1;            //LED0灭
				while(PCin(6) == 0);  
				Infrared_LED0 = 0;
			}
			else
				LED_0 = 0;            //LED0亮
	}
}

2、实验效果

在这里插入图片描述

五、HAL库使用红外传感器

1、cubemx的主要配置


在这里插入图片描述

在这里插入图片描述
③中断引脚
在这里插入图片描述
在这里插入图片描述
④中断通道
在这里插入图片描述

⑤LED引脚(请参考自己开发板的原理图)
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2、实验程序

函数变量:

static uint8_t LED0_Infrared = 0;  //检测红外信号的标志

主函数
在这里插入图片描述

if(LED0_Infrared == 1)  //检测到红外信号
{
	LED0_Infrared = 0;  
	HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);  //灯亮 
	while(!HAL_GPIO_ReadPin(Infrarred_GPIO_Port, Infrarred_Pin)); //等待手离开
}
else
{
	HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET); //灯灭
}

回调函数
在这里插入图片描述

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == GPIO_PIN_6)  //检测到红外信号
		LED0_Infrared = 1;
	__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_6);  //清除中断标志
}

3、实验效果

在这里插入图片描述
到这里就结束啦!

在这里插入图片描述

### STM32 HAL实现红外循迹PID控制 在嵌入式开发领域,STM32微控制器因其高性能和丰富的外设资源而被广泛应用于各种项目中。通过HAL可以简化硬件抽象层的操作,从而更方便地实现复杂功能,例如基于红外传感器的循迹控制以及PID算法的应用。 #### PID控制简介 比例-积分-衍生(Proportional Integral Derivative, PID)是一种常见的闭环控制系统算法,用于调节系统的动态行为并减少误差[^1]。其核心思想是通过对输入信号的比例、积分和导数项加权求和来计算输出值,最终达到稳定目标的目的。 对于红外循迹应用来说,通常会利用多个红外反射传感器检测地面颜色变化情况作为反馈数据源;再经过处理后送入到PID模块当中去调整电机转速差值进而改变机器人行驶方向直至回到轨迹线上为止。 #### 使用STM32 HAL编写红外循迹PID程序框架 以下是采用C语言编写的简单示例代码片段展示如何结合上述提到的技术要点完成整个流程: ```c #include "stm32f4xx_hal.h" // 定义全局变量 float kp = 0.8; // 比例系数 float ki = 0.05; // 积分系数 float kd = 0.2; // 微分系数 int error_prev = 0; int integral_sum = 0; void SystemClock_Config(void); static void MX_GPIO_Init(void); int main(void){ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); while (1){ int sensor_value = ReadInfraredSensor(); // 获取当前红外传感器读数 int setpoint = 1024 / 2; // 设定理想位置(假设满量程为1024) int error = setpoint - sensor_value; // 计算偏差 integral_sum += error; // 累积误差 float derivative = error - error_prev; // 当前时刻上一时刻误差之差即为微分校正部分 error_prev = error; // 更新上次误差记录以便下次循环使用 float output = kp * error + ki * integral_sum + kd * derivative; ControlMotor(output); // 将结果传递给驱动函数以影响左右轮速度差异度 } } /** * @brief Reads the value from infrared sensor. */ int ReadInfraredSensor(){ // 实现具体读取逻辑... return ADC_ReadChannel(INFRARED_SENSOR_CHANNEL); } /** * @brief Adjusts motor speed based on control signal. * @param[in] correction The calculated adjustment needed by PID controller. */ void ControlMotor(float correction){ if(correction > THRESHOLD){ // 如果超出阈值则加速一侧马达减速另一侧形成转向效果 SetLeftMotorSpeed(BASE_SPEED - abs((int)correction)); SetRightMotorSpeed(BASE_SPEED + abs((int)correction)); }else{ SetBothMotorsToBaseSpeed(); // 否则保持直线前进状态 } } ``` 以上仅为基本结构示意,在实际工程实践中还需要考虑更多细节比如限幅防饱和措施防止过度累积造成震荡现象等问题都需要妥善解决才能获得良好性能表现[^2].
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

修成真

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值