系列文章目录
一、基于STM32F103C8T6最小系统板和STM32CubeMX实现LED灯循环闪烁
二、基于STM32F103C8T6和STM32CubeMX实现UART串口通信数据收发
三、实战小例程 基于STM32F103C8T6最小系统板和STM32CubeMX驱动WS2812B光立方
四、基于STM32F103C8T6最小系统板HAL库CubeMX驱动HC-SR501红外人体传感模块
五、基于STM32F103C8T6(HAL库)的HC-SR501红外人体传感及HC-SR04超声波测距
前言
我在上一篇文章中驱动了HC-SR501红外人体传感模块,但在测试过程中发现,这个模块的热释电探头过于灵敏了,甚至有的时候往上哈气,会因为检测到类似于人体的温度而误判为感应到人体,所以为了减少误判概率,我打算再添加一个测距模块,在红外感应到人体时,再次判断人体与传感器的距离,在满足预设的距离范围时,才确定有人体接近,进行后续操作。一、模块简介
HC-SR501红外人体感应模块资料介绍:
探究人体红外传感器HC-SR501
HC-SR04超声波测距模块资料介绍:
引脚名称 | 引脚作用 |
---|---|
VCC | 3-5.5V供电(实测发现可以3.3V供电,但没有5V供电测得准) |
GND | 接地 |
Trig | 外部触发信号输入,输入一个高于10μs的高电平即可触发模块测距 |
Echo | 回响信号输出,测距结束时此管脚输出一个高电平,电平宽度反映超声波往返时间之和 |
工作原理:
简而言之:
给Trig一个10μS以上的高电平,模块开始工作,模块内自动发送八个40khz方波,并自主检测是否有电波返回。此时需要检测Echo处的电平,当为高电平的时候记一个时间;当Echo出为低电平的时候再记一个时间,这两个时间的差就是高电平持续的时间,最后用测距公式进行计算。
二、配置CubeMX
1、新建工程;
2、配置时钟源,在RCC里面的HSE配置的是晶振时钟;
3、配置程序烧录引脚SYS为SWD模式;
4、配置GPIO输出口,配置一个LED灯(我的板子是PC13),起到检测到人体时的指示作用;
5、配置GPIO输入口,用来读取HC-SR501模块的输出电平,我选的是PA1口;
6、配置GPIO输入口,用来检测HC-SR04超声波测距模块的回响信号输出,我选择PB5口,命名为HC_SR04_Echo_Pin;
7、配置GPIO输出口,用来触发HC-SR04超声波测距模块,我选择PB4口,命名为HC_SR04_Trig_Pin;
8、使能定时器,用来实现微秒延时,和测量HC-SR04模块高电平时间,我选择TIM2,并使能TIM2中断;
TIM2挂载在APB1,时钟来源频率为36MHz,故取预分频系数PSC=36-1
,计数周期Counter
设为60000-1
。即此时定时器频率为36M/36=1MHz,每60ms进一次中断,60000μs对应实际测距范围大概为10m,远远超过我的需求。
9、配置串口收发引脚;
10、配置时钟树,我还是开到最高的72MHz;
11、进行项目设置,最后生成代码,CubeMX部分就大功告成了
三、硬件连线部分
CH340 ↔ STM32F103C8T6最小系统板:
TX ↔ RX
RX ↔ TX
DAP-LINK ↔ STM32F103C8T6最小系统板
3.3V ↔ VCC
GND ↔ GND
SWIO ↔ SWIO
SWCLK ↔ SWCLK
HC-SR501模块 ↔ STM32F103C8T6最小系统板
OUT ↔ PA1
GND ↔ GND
HC-SR501模块 ↔ DAP-LINK (这里注意模块供电范围为4.5V-20V,用3.3V无法驱动)
VCC ↔ 5V
HC-SR04模块 ↔ CH340
VCC ↔ 5V
HC-SR04模块 ↔ STM32F103C8T6最小系统板
Trig ↔ PB4
Echo ↔ PB5
GND ↔ GND
四、逻辑代码部分
代码框架是基于上一篇HC-SR501红外人体感应模块修改而成的,想要完整代码的话可以和上篇文章一起看。
HC_SR04.c
#include "main.h"
#include "HC_SR04.h"
#include "stm32f1xx_hal.h"
#include "stm32f1xx_it.h"
static float distance_result;
/*
*********************************************************
函数原型:void Delay_us(uint16_t time)
函数输入:无符号整形
函数输出:无
函数功能:利用定时器实现微秒级延时
*********************************************************
*/
void Delay_us(uint16_t time)
{
uint16_t a1=TIM2->CNT;
while(TIM2->CNT-a1<time);
}
/*
*********************************************************
函数原型:void HC_SR04_startrange(void)
函数输入:无
函数输出:无
函数功能:从trig引脚生成一个不小于10us的高电平触发测距,触发后模块自动产生8个40kHz方波,自动检测是否有信号返回
*********************************************************
*/
void HC_SR04_startrange(void)
{
HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_SET);
//HAL_Delay(5);
Delay_us(10);
HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_RESET);
}
/*
*********************************************************
函数原型:uint16_t HC_SR04_gettime(void)
函数输入:无
函数输出:无符号整型
函数功能:通过定时器获取当前时间
*********************************************************
*/
uint16_t HC_SR04_gettime(void)
{
uint32_t a;
a=TIM2->CNT;
return a;
}
/*
*********************************************************
函数原型:float HC_SR04_getdistance(void)
函数输入:无
函数输出:浮点型
函数功能:获取与目标之间的距离
*********************************************************
*/
float HC_SR04_getdistance(void)
{
uint16_t time_node1;
uint16_t time_node2;
uint16_t measure;
HC_SR04_startrange();
TIM2->CNT = 0;
//有信号返回则通过IO口Echo输出高电平,高电平持续时间即为超声波从发射到返回的时间,测试距离=( 高电平时间*声速(340m/s) )/ 2
while(HAL_GPIO_ReadPin(HC_SR04_Echo_GPIO_Port,HC_SR04_Echo_Pin)==RESET);
time_node1=HC_SR04_gettime();
while(HAL_GPIO_ReadPin(HC_SR04_Echo_GPIO_Port,HC_SR04_Echo_Pin)==SET);
time_node2=HC_SR04_gettime();
measure=time_node2-time_node1;
distance_result = measure * 17.0/1000;//距离=计数差值(us) / 1000000 * 340(m/s) * 100 / 2 = measure * 17/1000
return distance_result;
}
HC_SR04.h
#ifndef _HC_SR04_H_
#define _HC_SR04_H_
void Delay_us(uint16_t time);
void HC_SR04_startrange(void);
float HC_SR04_getdistance(void);
uint16_t HC_SR04_gettime(void);
#endif
main.c
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == 1)
{
//HAL_Delay(50);
HC_SR04_distance=HC_SR04_getdistance();
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);//灭灯
printf("有人,目前距离为:%.2f cm\r\n",HC_SR04_distance);
HAL_Delay(100);
}
else
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);//亮灯
printf("没人\r\n");
HAL_Delay(1000);
}
// printf("hellp\r\n");
// HAL_Delay(1000);
}
/* USER CODE END 3 */
}
现象:
感应到人体,板载LED绿灯亮,同时串口打印测距结果。
注意:
重定义printf后,必须在target里面勾选上MicroLIB,调用一下这个微型库,不然一直卡在里面。
文章来源:https://www.toymoban.com/news/detail-416725.html
参考博客:
stm32f1驱动HC-SR04超声波测距模块文章来源地址https://www.toymoban.com/news/detail-416725.html
到了这里,关于基于STM32F103C8T6(HAL库)的HC-SR501红外人体传感及HC-SR04超声波测距的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!