1.硬件
- STM32单片机最小系统
- HC-SR04超声波模块
2.软件
- hcsr04驱动文件添加
- main.c程序
c
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"
#include "hcsr04.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
led_init(); /* 初始化LED灯 */
uart1_init(115200);
hcsr04_init();
printf("hello world!\r\n");
while(1)
{
printf("dis: %.2f\r\n", hcsr04_get_length());
delay_ms(1000);
}
}
- hcsr04.c程序
c
#include "hcsr04.h"
#include "delay.h"
TIM_HandleTypeDef tim2_handle = {0};
//定时器初始化函数
void tim2_init(void)
{
tim2_handle.Instance = TIM2;
tim2_handle.Init.Prescaler = 72 - 1;//定时器溢出时间计算
tim2_handle.Init.Period = 65536 - 1;//根据超声波最大测距距离
tim2_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
tim2_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_Base_Init(&tim2_handle);
}
//msp函数
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
__HAL_RCC_TIM2_CLK_ENABLE();
}
}
void tim2_start(void)//定时器启动函数
{
HAL_TIM_Base_Start(&tim2_handle);
}
void tim2_stop(void)//定时器关闭函数
{
HAL_TIM_Base_Stop(&tim2_handle);
}
uint16_t tim2_get_cnt(void)//读取cnt计数值
{
return __HAL_TIM_GetCounter(&tim2_handle);
}
void tim2_set_cnt(uint16_t val)//设置计数器值
{
__HAL_TIM_SetCounter(&tim2_handle, val);
}
void hcsr04_gpio_init(void)
{
GPIO_InitTypeDef gpio_initstruct;
//打开时钟
TRIG_GPIO_CLK_ENABLE();//宏定义PB管脚时钟
ECHO_GPIO_CLK_ENABLE();
//初始化Trig引脚(输出引脚)
gpio_initstruct.Pin = TRIG_PIN;//PB6
gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_initstruct.Pull = GPIO_NOPULL;
gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(TRIG_PORT, &gpio_initstruct);
//初始化Echo引脚(输入引脚)
gpio_initstruct.Pin = ECHO_PIN;//PB7
gpio_initstruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(ECHO_PORT, &gpio_initstruct);
}
void hcsr04_init(void)
{
tim2_init();
hcsr04_gpio_init();
}
float hcsr04_get_length(void)
{
uint16_t total_time = 0;
float distance = 0;
//1. Trig,给Trig端口至少10us的高电平
TRIG_HIGH();//高电平
delay_us(15);//延时15us
TRIG_LOW();//低电平
//2. Echo引脚,由低电平跳转到高电平,表示开始发送波
//波发出去的那一下,开始启动定时器
while(ECHO_STATUS() == GPIO_PIN_RESET);
tim2_start();//启动定时器
tim2_set_cnt(0);//清空计数器
//3. Echo,由高电平跳转回低电平,表示波回来了
//波回来的那一下,我们开始停止定时器,计算出中间经过多少时间
while(ECHO_STATUS() == GPIO_PIN_SET);
tim2_stop();//关闭定时器
//4. 计算出中间经过多少时间
total_time = tim2_get_cnt();//获取定时器中计数器值
//5. 距离 = 速度(343m/s) * 时间 / 2
distance = total_time * 0.01715;
return distance;
}
- sg90.h程序
c
#ifndef __HCSR04_H__
#define __HCSR04_H__
#include "sys.h"
//宏定义
#define TRIG_PORT GPIOB
#define TRIG_PIN GPIO_PIN_6
#define TRIG_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define TRIG_HIGH() HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET)
#define TRIG_LOW() HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET)
#define ECHO_PORT GPIOB
#define ECHO_PIN GPIO_PIN_7
#define ECHO_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define ECHO_STATUS() HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN)
void hcsr04_init(void);
float hcsr04_get_length(void);
#endif
3.实物效果
- 硬件模块接线
HC-SR04 | STM32 |
---|---|
Trig | PB6 |
Echo | PB7 |
VCC | 5V |
GND | GND |
- 实验现象
通过USB转TTL串口模块,将STM32单片机与电脑连接,打开串口软件,设置波特率115200,可以看到串口打印处超声波模块所测量的距离。