人体红外感应模块详解

发布者:GoldenEclipse最新更新时间:2025-02-08 来源: jianshu关键字:stm32  HC-SR501 手机看文章 扫描二维码
随时随地手机看文章

随着自动化和智能化技术的发展,人体红外感应模块在许多领域得到了广泛应用,比如安防系统、自动照明和自动门。

HC-SR501 就是一款高效、稳定的人体红外感应模块,它基于热释电效应,能够精确地检测人体或动物的红外线。在接下来的文章中,我们将深入了解 HC-SR501 模块的特点、工作原理以及如何应用。


1. 源码下载及前置阅读

本文所涉及的源码及安装包如下(由于平台限制,请点击以下链接阅读原文下载):

https://www.lxlinux.net/e/stm32/hc-sr501-tutorial.html

超全的嵌入式入门教程,欢迎小白。

  • 从零开始轻松掌握STM32开发的必备指南:零基础快速上手STM32开发(手把手保姆级教程)

  • 使用接收中断+超时判断完成不定长数据的接收:STM32串口接收不定长数据(空闲中断+DMA)

  • 一文教你使用STM32CubeMX开发工具

往期精彩教程,有兴趣的小伙伴可以看看。

  • 实现物联网数据采集与远程监控:小项目:使用MQTT上传温湿度到Onenet服务器

  • 蓝牙模块详解,轻松掌握一种无线通信技术:手把手教你玩转蓝牙模块(原理+驱动)

  • 简单好用,为你的智能语音项目提供核心支持:SU-03T语音控制模块详解

作者简介
大家好,我是良许,博客里所有的文章皆为我的原创。
下面是我的一些个人介绍,欢迎交个朋友:
· 211工科硕士,国家奖学金获得者;
· 深耕嵌入式11年,前世界500强外企高级嵌入式工程师;
· 书籍《速学Linux作者》,机械工业出版社专家委员会成员;
· 全网60W粉丝,博客分享大量原创成体系文章,全网阅读量累计超4000万;
· 靠自媒体连续年入百万,靠自己买房买车。

我本科及硕士都是学机械,通过自学成功进入世界500强外企。我已经将自己的学习经验写成了一本电子书,超千人通过此书学习并转行成功。现在将这本电子书免费分享给大家,希望对你们有帮助:

电子书链接:https://www.lxlinux.net/1024.html

2. HC-SR501介绍

人体红外感应模块大家族有很多成员,给大家看看部分成员的样貌。HC-SR501 蓝板和绿板只是颜色不同。

HC-SR501是基于红外线技术的自动控制模块,采用德国原装进口 LHI778 探头设计,灵敏度高,可靠性强,超低电压工作模式,广泛应用于各类自动感应电器设备,尤其是干电池供电的自动控制产品。

白色的半球体是菲涅耳透镜,拆下它,里面长这样。探头用于检测人体红外,预留的两个接口在下文会提到并解释。

2.1 HC-SR501功能特点

  1. 全自动感应:人进入其感应范围则输出高电平,人离开感应范围则自动延时关闭高电平,输出低电平。

  2. 光敏控制(可选择,出厂时未设)可设置光敏控制,白天或光线强时不感应。(使用光敏电阻接口)

  3. 温度补偿(可选择,出厂时未设):在夏天当环境温度升高至30~32℃,探测距离稍变短,温度补偿可作一定的性能补偿。(使用热敏电阻接口)

  4. 两种触发方式(跳线选择):(1)不可重复触发方式:即感应输出高电平后,延时时间段一结束,输出将自动从高电平变成低电平;(2)可重复触发方式:即感应输出高电平后,在延时时间段内,如果有人体在其感应范围活动,其输出将一直保持高电平,直到人离开后才延时将高电平变为低电平。

  5. 具有感应封锁时间(默认设置:2.5秒封锁时间):感应模块在每一次感应输出后(高电平变成低电平),可以紧跟着设置一个封锁时间段,在此时间段内感应器不接受任何感应信号。此功能可以实现“感应输出时间”和“封锁时间”两者的间隔工作,可应用于间隔探测产品;同时此功能可有效抑制负载切换过程中产生的各种干扰。

  6. 工作电压范围宽:工作电压 DC4.5V-20V。

  7. 微功耗:静态电流<50微安。

  8. 输出高电平信号:可方便与各类电路实现对接。

2.2 HC-SR501使用说明

  1. 感应模块通电后有一分钟左右的初始化时间,在此期间模块会间隔地输出0-3次,一分钟后进入待机状态。

  2. 避免灯光等干扰源近距离直射模块表面的透镜,以免引进干扰信号产生误动作;尽量避免流动的风,风也会对感应器造成干扰。

  3. 感应模块采用双元探头,探头的窗口为长方形,双元(A元、B元)位于较长方向的两端,当人体从左到右或从右到左走过时,红外光谱到达双元的时间、距离有差值,差值越大,感应越灵敏,当人体从正面走向探头或从上到下或从下到上方向走过时,双元检测不到红外光谱距离的变化,无差值,因此感应不灵敏或不工作;所以安装感应器时应使探头双元的方向与人体活动最多的方向尽量相平行,保证人体经过时先后被探头双元所感应。为了增加感应角度范围,本模块采用圆形透镜,也使得探头四面都感应,但左右两侧仍然比上下两个方向感应范围大、灵敏度强,安装时仍须尽量按以上要求。

  4. 人体红外感应模块应离地面2.0-2.2米。

  5. 人体红外感应模块远离空调, 冰箱,火炉等空气温度变化敏感的地方。

  6. 人体红外感应模块探测范围内不得隔屏、家具、大型盆景或其他隔离物。

  7. 人体红外感应模块不要直对窗口,否则窗外的热气流扰动和人员走动会引起误报,有条件的最好把窗帘拉上。红外线热释电传感器也不要安装在有强气流活动的地方。

安装方面简单来说就是要避开温度干扰、气流干扰和大型障碍。

3. 工作原理

HC-SR501 工作时,探头检测到有人移动时,输出1;没人移动时,输出0。

那么原理是什么呢?

在解释原理前,我们先解释两个名词。

  • 菲涅耳透镜

根据菲涅耳原理制成,有如下特点:

  1. 聚焦作用:菲涅耳透镜可以将入射光线聚焦到一个点上,实现光线的集中和聚焦效果。这使得菲涅耳透镜在许多光学系统中被广泛使用,如摄影镜头、望远镜、投影仪等。

  2. 红外感应:菲涅耳透镜也常用于红外传感器和人体感应模块中。通过对红外辐射的聚焦作用,它能够增强红外信号的接收灵敏度,并提高红外传感器的性能。

  3. 分区控制:菲涅耳透镜的表面通常被划分为若干个明暗区域,使得光线能够以不同的路径通过透镜。这种设计可以用于光控制系统中,例如调节照明亮度、防眩光等应用。

  • 热释电效应

当一些晶体受热时,在晶体两端将会产生数量相等而符号相反的电荷。这种由于热变化而产生的电极化现象称为热释电效应。

知道了这两个名词后,我们就能理解 HC-SR501 的工作原理了。

  1. 我们的人体的体温大概在37度,会发出特定波长 10μm 左右的红外线,HC-SR501 上的红外探头就是靠探测人体发射的 10μm 左右的红外线而进行工作的。当然,如果是体温相似的动物也会被检测到。

  2. 人体发射的 10μm 左右的红外线通过菲泥尔滤透镜增强后聚集到红外感应源上。

  3. 红外感应源通常采用热释电元件,这种元件在接收到人体红外辐射温度发生变化时就会失去电荷平衡,向外释放电荷,后续电路经检测处理后就能产生报警信号。

4. 工作参数及引脚介绍

HC-SR501 模块工作参数,每个厂家会有点不同:

  1. 工作电压:DC 4.5V至20V

  2. 静态功耗:<50微安

  3. 电平输出:高3.3V,低0V

  4. 延时时间:可调(8秒~200秒)

  5. 封锁时间:2.5秒

  6. 触发方式:L不可重复,H可重复,默认值为H(跳帽选择)

  7. 感应范围:小于120度锥角,7米以内

  8. 工作温度:-15° ~ +70°

调节和接线参考如下:

5. 编程实战

5.1 通信示意图

我们的实现目标是:当有人经过时,红灯亮起,无人时,红灯灭。

5.2 硬件连接

本教程使用的硬件如下:

  • 单片机:STM32F103C8T6

  • 人体红外感应模块:HC-SR501

  • 小灯:三色 LED 灯模块

  • 烧录器:ST-LINK V2

HC-SR501模块STM32LED
5V5V
输出A4
GNDG

A5R

GGND

烧录的时候接线如下表,如果不会烧录的话可以看我之前的文章【STM32下载程序的五种方法】。

ST-Link V2STM32
SWCLKSWCLK
SWDIOSWDIO
GNDGND
3.3V3V3

接好如下图:

开发板使用的是我们自绘的板子。大家也可以用自己的板子,只要是 STM32F103C8T6 主控芯片就行。

5.3 LED初始化

LED 灯的代码简简单单,只要进行一下三个灯的初始化就行,虽然本项目我们只用到红灯(LED1),但是其他两个灯就我也就懒得删了。


void led_init(void)

{

    GPIO_InitTypeDef gpio_init_struct;

    LED1_GPIO_CLK_ENABLE();                                 /* LED1时钟使能 */

    LED2_GPIO_CLK_ENABLE();                                 /* LED2时钟使能 */

    LED3_GPIO_CLK_ENABLE();                                 /* LED3时钟使能 */


    gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引脚 */

    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽输出 */

    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */

    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */

    HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引脚 */


    gpio_init_struct.Pin = LED2_GPIO_PIN;                   /* LED2引脚 */

    HAL_GPIO_Init(LED2_GPIO_PORT, &gpio_init_struct);       /* 初始化LED2引脚 */

    

    gpio_init_struct.Pin = LED3_GPIO_PIN;                   /* LED3引脚 */

    HAL_GPIO_Init(LED3_GPIO_PORT, &gpio_init_struct);       /* 初始化LED3引脚 */


    LED1(0);                                                /* 关闭 LED1 */

    LED2(0);                                                /* 关闭 LED2 */

    LED3(0);                                                /* 关闭 LED3 */

}


LED 的 .h文件:

#ifndef _LED_H

#define _LED_H

#include 'sys.h'



/******************************************************************************************/

/* 引脚 定义 */


#define LED1_GPIO_PORT                  GPIOA

#define LED1_GPIO_PIN                   GPIO_PIN_5

#define LED1_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)             /* PA口时钟使能 */


#define LED2_GPIO_PORT                  GPIOA

#define LED2_GPIO_PIN                   GPIO_PIN_6

#define LED2_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)             /* PA口时钟使能 */


#define LED3_GPIO_PORT                  GPIOA

#define LED3_GPIO_PIN                   GPIO_PIN_7

#define LED3_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)             /* PA口时钟使能 */


/******************************************************************************************/

/* LED端口定义 */

#define LED1(x)   do{ x ?

                      HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) :

                      HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET);

                  }while(0)


#define LED2(x)   do{ x ?

                      HAL_GPIO_WritePin(LED2_GPIO_PORT, LED2_GPIO_PIN, GPIO_PIN_SET) :

                      HAL_GPIO_WritePin(LED2_GPIO_PORT, LED2_GPIO_PIN, GPIO_PIN_RESET);

                  }while(0)


#define LED3(x)   do{ x ?

                      HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_SET) :

                      HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_RESET);

                  }while(0)


/* LED取反定义 */

#define LED1_TOGGLE()   do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0)        /* 翻转LED1 */

#define LED2_TOGGLE()   do{ HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_GPIO_PIN); }while(0)        /* 翻转LED2 */

#define LED3_TOGGLE()   do{ HAL_GPIO_TogglePin(LED3_GPIO_PORT, LED3_GPIO_PIN); }while(0)        /* 翻转LED3 */


/******************************************************************************************/

/* 外部接口函数*/

void led_init(void);                                                                            /* LED初始化 */


#endif


5.4 HC-SR501初始化

代码很简单,就是初始化一下输出引脚,PA4。

我们采用中断的方式点灯,需要初始化和使能一下 EXTI。

void hs_gpio_init(void)

{

    GPIO_InitTypeDef GPIO_InitStruct = {0};


    /* GPIO Ports Clock Enable */

    __HAL_RCC_GPIOA_CLK_ENABLE();


    /*Configure GPIO pins : PA4 */

    GPIO_InitStruct.Pin = GPIO_PIN_4;

    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;             //中断上升沿

    GPIO_InitStruct.Pull = GPIO_NOPULL;                     //无电阻

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


    /* EXTI interrupt init*/

    HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0);                 //抢占2,子优先级0

    HAL_NVIC_EnableIRQ(EXTI4_IRQn);

}

5.5 中断服务函数

设计中断服务函数,PA4 检测到上升沿,高电平,「hsflag」置1。

uint16_t get_hsflag(void)

{

    return hsflag;

}


void set_hsflag(uint16_t value)

{

    hsflag = value;

}


void EXTI4_IRQHandler(void)

[1] [2]
关键字:stm32  HC-SR501 引用地址:人体红外感应模块详解

上一篇:小项目:蓝牙模块点亮RGB三色灯
下一篇:电机驱动模块L9110S详解

推荐阅读最新更新时间:2026-03-24 11:54

HC-SR501热释电红外传感器驱动(STM32
一、前期准备 单片机:STM32F103ZET6 开发环境:MDK5.14 库函数:标准库V3.5 HC-SR501热释电红外传感器模块:淘宝有售 二、实验效果 三、驱动原理 这个模块比较简单,当有人靠近时候其IO输出3.3V,STM32可以直接采集。 需要完整工程或者有问题的请加QQ:1002521871,验证:呵呵。 四、驱动代码 HC_SR501.h #ifndef __HC_SR501_H__ #define __HC_SR501_H__ #include stm32f10x.h #include gpio.h #include delay.h #define HC_SR501 PA
[单片机]
<font color='red'>HC-SR501</font>热释电<font color='red'>红外</font>传感器驱动(<font color='red'>STM32</font>)
基于STM32的矿井作业环境监测系统设计与实现
针对煤矿开采中瓦斯爆炸等严重安全隐患,设计了一套矿井安全系统。该系统实时监测瓦斯浓度、温度、火情、粉尘等环境参数,自动控制除尘、灭火、通风等设备,以保障矿井安全。通过WiFi将数据传输至监控平台,并支持APP远程监控与操作,从而提升应急响应速度和管理效率。 PART 01 系统总体结构 系统实现了对矿井内甲烷气体体积分数、粉尘浓度、火焰及温湿度等关键参数的实时采集与分析;并通过预设的自动控制策略触发联动设备,实现安全隐患的快速响应与主动防控。同时,支持数据远程传输至云端平台,并通过机智云APP提供实时监控、报警及远程操控功能,为矿井安全管理提供高效、可靠的技术支撑。系统总体结构如图1所示。 PART 02 系统详细设计
[单片机]
基于<font color='red'>STM32</font>的矿井作业环境监测系统设计与实现
【07】STM32备忘_RTC硬件电路设计
正点原子的 STM32F103官方文档
[单片机]
野火STM32学习笔记(构建库函数模型第五节课)
解释初始化函数是怎么运作的 第四节课我们已经了解了如何通过固件库编程的方式初始化一个GPIO口,配置其速度,工作模式等等,这一切都有一个“幕后黑手”就是那一个一百多行的GPIO_Init()函数。我们再来一睹一下芳容: 第一部分 我们从第一行开始看: 大括号内第一二行都是存放这些变量的初始值,可以不用太在意。再看下面模式配置那边,第一行注释是把模式的低四位存入变量currentmode,这样做的目的是取出这些值(与0x0F相与取值),再判断它的bit4位是几(如下图),是0则是输入,是1则是输出,判断方式也很简单,即赋值给currentmode的值和0x10(二进制00010000)与运算,看看是不是0就知
[单片机]
STM32读写W25Q
硬件外观 引脚说明 关于如何接线? 1,CS2,MISO3,3.3V4,GND5,MOSI6,SCK7,3.3V8,3.3V 关于如何查询芯片引脚?(打开STM32手册) 代码摘要 这段来自野火源码,需要修改的是芯片地址 程序的流程是预先设置一个地址,也就是上面的地址,然后在程序跑起来的时候读取芯片的地址,读取 地址后与预先设置的地址对照,然后打印提示信息。 int main(void) { /* 配置串口为:115200 8-N-1 */ USART_Config(); printf( rn 这是一个8Mbyte串行flash(W25Q64)实验 rn ); /* 8M串行flash W25Q
[单片机]
基于STM32的Flash读写详解
前言 本文主要介绍STM32多种的内部Flash读写方式和读写长文件的功能函数怎样编写。阅读完本文可以使你能够正常的完成Flash读写操作。 介绍 STM32 FLASH 不同型号的 STM32,其 FLASH 容量也有所不同,最小的只有 16K 字节,最大的则达到了1024K 字节。本次实验选用的STM32 开发板是F103ZET6,其 FLASH 容量为 512K 字节,属于大容量产品(另外还有中容量和小容量产品),大容量产品的闪存模块组织如图 所示: STM32 的闪存模块由:主存储器、信息块和闪存存储器接口寄存器等 3 部分组成。 主存储器,该部分用来存放代码和数据常数(如 const 类型的数据)。对于大容量产品
[单片机]
STM32的项目创建——基于Keil MDK环境
Keil MDK是比较流行的STM32项目开发工具,建议选用5.0以上的版本,同时要注意5.0版本对Windows XP、Window7的支持已经不好了,因此在开发平台上也建议选用Windows 10或以上版本。 另外,Mac系统和Linux系统也可以使用Keil MDK,操作方式类似,这里不做赘述。 创建MDK工程 首先,介绍新建工程的方法,工程创建基于C8T6,要保证在建立前,已经安装了Keil MDK及对应STM32F1的工具包“Keil.STM32F1xx_DFP”。 1、新建工程目录 创建一个文件夹作为新工程的目录,关于此步骤提出两点建议: 一是最好采用“工作空间- 工程目录”的方式
[单片机]
stm32 ,DMA,adc,fft. . .(基于库函数)
用TIM2定时器触发adc,DMA采集之后进行fft转换. fft是一种快速傅里叶算法. 官方给的256点运算时间仅需要0.362ms,1024点也只要2.138ms(72mHz) 傅里叶变换就像是将一桶各个颜色混杂在一起的油漆分离出来.并将每种颜料的含量也计算出来. 而各种颜色代表了各种频率,含量代表幅值.(个人的浅显理解) 了解个差不多就可以开始了~ 先将fft的官方库添加到自己的工程.(https://pan.baidu.com/s/1Gw1NXCa3q8SHxc-E1H-6yw 提取码:m1et) 添加之后可以看到官方提供了两种快速傅里叶变换函数,分别为256点和1024点.这里视自己情况进行使用.不过要注意在这之前要调用
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved