基于STM32的HC-SR04超声波测距模块实验
硬件环境
STM32F407探索板(其他开发板皆可以)
HC-SR04超声波模块
软件环境
KEIL5
CUBEMX
串口调试助手(sscom或其他)
实验目标
了解HC-SR04超声波模块工作原理 实现超声波模块测距
1、超声波模块介绍
1.1 超声波测距原理及系统组成
基本原理:经发射器发射出长约 6mm,频率为 40KHZ 的超声波信号。此信号被物 体反射回来由接收头接收,接收头实质上是一种压电效应的换能器。它接收到信号后产 生 mV 级的微弱电压信号。
1.2 HC-SR04模块原理
如上图接线,VCC供5V电源,GND为地线,TRIG触发控制信号输入,ECHO 回响信号输出等四个接口端。
1.3 超声波时序图
1.4 电气参数
电气参数 | HC-SR04模块 |
---|---|
工作电压 | DC5V |
工作电流 | 15mA |
工作频率 | 40KHZ |
最远射程 | 4M |
最近射程 | 2CM |
测量角度 | 15度 |
输入触发信号 | 10uS 的 TTL 脉冲 |
输出回响信号 | 输出 TTL 电平信号,与射程成比例 |
规格尺寸 | 45*20*15mm |
2、软件实现
2.1 硬件连接
单片机 | HC-SR04模块 |
---|---|
5V | VCC |
Trig | PB14 |
Echo | PB15 |
GND | GND |
2.2 cubemx配置
我板子上焊接的是8M的晶体,如果小伙伴们的板子上不是8M,根据自己的晶振频率配置即可,左侧圈1中,可以根据自己的晶体频率,输入相应的频率,经过分频、倍频后,系统时钟频率设置为最大,168MHZ,APB1的时钟频率为 84MHZ,也是后面用到的 TIM2 挂载的时钟源的频率。
配置串口1作为我们调试输出串口,配置如下图
接下来,配置超声波模块用到的IO,PB14作为Trig引脚,配置为输出模式,PB15作为Echo引脚,配置为输入模式
2.3 软件代码实现
#define HCSR_TRIG_HIGH() HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_SET)
#define HCSR_TRIG_LOW() HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_RESET)
#define HCSR_ECHO() HAL_GPIO_ReadPin(HC_SR04_ECHO_GPIO_Port,HC_SR04_ECHO_Pin)
void HCSR04StartTrigStart(void){ HCSR_TRIG_HIGH(); for_delay_us(20); HCSR_TRIG_LOW();}
/* TIM2 init function */
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 84-1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 65535;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}
//mode=1-->open timer //mode=0-->close timervoid HCSR04_TimerFunc(uint8_t mode){ if(mode) { __HAL_TIM_SetCounter(&htim2,0); HAL_TIM_Base_Start(&htim2); //HAL_TIM_Base_Start_IT(&htim2); msHcCount = 0; } else { HAL_TIM_Base_Stop(&htim2); //HAL_TIM_Base_Stop_IT(&htim2); }}
//单次获取测量距离
float HCSR04_Get_Distant(void)
{
HCSR04StartTrigStart();
while(!HCSR_ECHO());
HCSR04_TimerFunc(1);//start timer
while(HCSR_ECHO());
HCSR04_TimerFunc(0);//stop timer
return (__HAL_TIM_GetCounter(&htim2))/58.0;
}
//均值滤波减小测量误差
float Distance(uint8_t cnt)
{
float sum = 0;
for(int i =0;i<cnt;i++)
{
sum+=HCSR04_Get_Distant();
}
return sum/cnt;
}
distant = Distance(5); t++; if(t%5==0) { t=0; printf('\r\n\r\n---------------start--------------------\r\n\r\n'); printf('The Mesure Distant is:%.2f cm\r\n',distant); printf('\r\n\r\n----------------stop--------------------\r\n\r\n'); HAL_GPIO_TogglePin(led_run_GPIO_Port,led_run_Pin); } HAL_Delay(100);