人体红外传感器完整实验记录
前言
最近在做鸿蒙班 STM32L4 智能家居板实验,完成了AS312 热释电人体红外传感器(HC‑SR501) 的人体存在检测项目。实现功能:GPIO 读取人体红外信号、LCD 屏幕实时显示有人 / 无人状态、串口上报检测结果、软件定时采样 + 状态防抖,踩过的坑、原理、代码逻辑、现象全部整理出来,适合 STM32 嵌入式新手参考学习。
硬件平台:STM32L431VC 智能家居开发板 传感器:AS312(HC‑SR501)热释电人体红外传感器 开发库:STM32 HAL 库 调试工具:SSCOM 串口助手,波特率 115200
一、实验原理
HC‑SR501(AS312)属于热释电红外传感器,原理是捕捉人体发出的红外热辐射。
- 探测范围内检测到人体活动 → 输出高电平 1
- 范围内没有人活动 → 输出低电平 0
单片机通过 GPIO 输入引脚读取该电平信号,完成人体检测。
本实验整套链路: AS312人体红外传感器 → STM32 GPIO输入引脚 STM32 FSMC接口驱动LCD屏幕,展示检测状态图标+文字 USART2串口 → CH340 USB转串口 → PC端SSCOM串口助手打印日志
程序设计要点:
- 使用
HAL_GetTick()做软件计时,1000ms 采集一次传感器状态,不用占用硬件定时器 - 做状态记忆,只有状态发生改变才进行串口打印,避免串口刷屏产生大量冗余数据
- LED1 每秒电平翻转,作为程序运行心跳指示灯
- 简单软件防抖,过滤传感器瞬时抖动误触发
硬件连接:传感器信号输出引脚接到单片机PC8引脚,传感器供电 3.3V。
二、整体程序架构
整个项目分为三大模块:主函数模块、系统时钟配置模块、人体红外业务处理模块。
1. main.c 主函数入口
int main(void)
{
HAL_Init();
SystemClock_Config(); //系统时钟初始化
LCD_Display_Init(); //LCD屏幕初始化
gpio_module_open(LEDS); //LED引脚初始化
uart_open(uart2, 115200); //串口2初始化,波特率115200
printf("\r\n\t人体红外检测实验\t\r\n");
printf("----------------------------\r\n");
printf("开始本实验:\r\n\r\n");
AS312_Init(); //人体红外传感器GPIO初始化
printf("** 人体红外传感器初始化\r\n");
while(1)
{
Body_Handle(); //循环调用人体红外检测处理函数
}
}
执行流程:
HAL_Init()初始化 HAL 底层库,配置滴答定时器、中断优先级;- 依次初始化时钟、LCD 显示屏、LED、串口、人体红外传感器外设;
- 全部硬件初始化完成后进入
while(1)死循环,持续调用Body_Handle()处理检测逻辑,完成采集、屏幕刷新、串口输出、状态判断。
2. SystemClock_Config 系统时钟模块
系统时钟是所有外设工作的基础:
- 选择高速外部 HSE 或者内部 HSI 时钟源;
- 配置 PLL 锁相环倍频,生成系统主时钟 SYSCLK;
- 配置 AHB、APB 预分频,分配总线时钟;
- 开启 GPIO、串口等外设时钟,外设时钟不打开硬件将无法工作。
补充:
_Error_Handler()是 HAL 库错误回调。时钟配置失败、外设初始化异常会进入该函数,卡在死循环。调试时可以在这里增加屏幕打印,快速定位硬件、时钟配置故障。
3. Body_Handle () 核心业务处理函数
这是本实验的业务核心,主循环反复调用。
void Body_Handle(void)
{
static uint8_t as312_state_rev = 2;
uint8_t as312_state = 0;
static uint32_t tickstart;
if((HAL_GetTick() - tickstart) >= 1000) //1000ms采集一次
{
tickstart = HAL_GetTick();
as312_state = Infrared_Read_State(); //读取传感器电平
if(as312_state == 1)
{
//LCD绘制有人图标,显示someone
LCD_draw_bmp(96,120,48,gImage_Body);
LCD_Fill1(96,178,137,194,WHITE);
Show_Str(96,178,BLUE,WHITE,"someone",16,1);
}
else if(as312_state == 0)
{
//LCD绘制无人图标,显示no one
LCD_draw_bmp(96,120,48,gImage_Body_hui);
LCD_Fill1(96,178,137,194,WHITE);
Show_Str(96,178,BLUE,WHITE,"no one",16,1);
}
//状态发生变化才打印串口,减少冗余输出
if(as312_state != as312_state_rev)
{
if(as312_state == 1)
{
printf("** 读取人体红外传感器数据\r\n");
printf("** 人体红外传感数据:someone\r\n\r\n");
}
else if(as312_state == 0)
{
printf("** 读取人体红外传感器数据\r\n");
printf("** 人体红外传感数据:no one\r\n\r\n");
}
as312_state_rev = as312_state; //保存上一次状态
}
led_toggle(LED1_PORT); //翻转LED,作为运行指示
}
}
关键逻辑解读:
HAL_GetTick()实现软件 1 秒定时,周期性读取传感器;Infrared_Read_State()读取 PC8 引脚电平,返回 1 代表有人,0 代表无人;- 根据状态刷新 LCD 图标与文字;
- 使用静态变量保存上一回检测状态,状态改变才 printf 输出,防止串口疯狂刷屏;
- 每次采样完成翻转 LED1,直观证明程序正常在跑。
三、实验现象与结果
把程序下载到 STM32 开发板,PC 打开 SSCOM 串口助手:
- 参数设置:选择对应 COM 口,波特率
115200 - 上电后串口打印实验标题、初始化提示;LCD 屏幕显示标题 “人体红外检测实验”
- 人进入传感器探测范围 LCD 显示有人图标 +
someone;串口输出:
** 读取人体红外传感器数据
** 人体红外传感数据:someone
- 人离开探测范围 LCD 切换为无人图标 +
no one;串口输出:
** 读取人体红外传感器数据
** 人体红外传感数据:no one
- LED 指示灯每 1 秒翻转一次,代表程序持续运行。
⚠️注意:HC‑SR501 硬件自带延时,人走开之后不会立刻变为无人,是传感器硬件本身特性,不是程序 bug。
四、调试遇到的问题与排错
- 串口完全没有输出 排查:COM 端口是否选对、波特率是否 115200;检查 CH340 驱动;检查串口硬件接线、串口初始化代码。
- LCD 屏幕黑屏 / 无内容 排查 LCD 初始化函数,FSMC 硬件接线,屏幕电源。
- 传感器乱跳、误触发 热释电传感器容易受环境温度干扰,可以增加多次采样判断做软件滤波防抖。
感悟:串口打印是嵌入式调试最高效手段之一,很多硬件故障、逻辑问题都可以通过串口日志定位。
五、拓展创新思路
做完基础检测功能,还可以做二次开发:
- 入侵报警:检测到人触发蜂鸣器鸣叫,简单安防告警;
- 人体感应灯:外接继电器,检测到人自动开灯;
- 云端上报:对接 WiFi 模块,把有人 / 无人状态上传云平台,远程查看;
- 增强抗干扰:连续多次采样确认状态,降低误触发概率;
- 按键调参:增加按键,修改传感器采样周期,改变系统响应快慢。
总结
本次实验完整走完从硬件接线、GPIO 采集传感器信号、屏幕显示、串口上报的完整流程。 学会使用 HAL 库HAL_GetTick()做软件定时采样,理解状态记忆,解决串口输出刷屏的问题,同时认识热释电人体红外传感器的固有硬件特性。对于想要入门 STM32 智能家居项目,这个是非常适合上手的小 Demo。
更多推荐




所有评论(0)