通过HAL库使用STM32F103ZET6和HC-SR04开发超声波测距
时间: 2024-05-30 16:15:45 浏览: 122
基于stm32f103zet6的超声波测距 HC-SR04
5星 · 资源好评率100%
1. 硬件连接
将HC-SR04的VCC接到STM32F103ZET6的5V电源,GND接到GND,Trig接到STM32F103ZET6的PB0引脚,Echo接到STM32F103ZET6的PB1引脚。
2. 配置GPIO
使用HAL库配置PB0和PB1引脚为输出和输入模式,分别用来控制HC-SR04的Trig和读取Echo信号。
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOB_CLK_ENABLE(); // 使能GPIOB时钟
GPIO_InitStruct.Pin = GPIO_PIN_0; // PB0
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL; // 不带上下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1; // PB1
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 输入模式
GPIO_InitStruct.Pull = GPIO_NOPULL; // 不带上下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
3. 发送超声波信号
使用HAL库的GPIO_WritePin函数将Trig引脚输出高电平,持续10us,然后输出低电平。
void Send_Trigger_Pulse(void)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 输出高电平
HAL_Delay(10); // 持续10us
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 输出低电平
}
4. 接收回波信号
使用HAL库的pulseIn函数读取Echo引脚的信号,计算回波信号的时间差,再通过声速计算距离。
uint32_t pulseIn(uint16_t pin, uint8_t state, uint32_t timeout)
{
uint32_t start, end;
GPIO_PinState bit;
start = HAL_GetTick(); // 获取当前时间
do {
end = HAL_GetTick(); // 获取当前时间
if (end - start > timeout) return 0; // 超时返回0
bit = HAL_GPIO_ReadPin(GPIOB, pin); // 读取引脚状态
} while (bit != state); // 等待状态变化
start = HAL_GetTick();
do {
end = HAL_GetTick();
if (end - start > timeout) return 0;
bit = HAL_GPIO_ReadPin(GPIOB, pin);
} while (bit == state); // 等待状态变化
return end - start; // 返回时间差
}
float Measure_Distance(void)
{
uint32_t duration;
float distance;
Send_Trigger_Pulse(); // 发送超声波信号
duration = pulseIn(GPIO_PIN_1, GPIO_PIN_SET, 1000); // 读取回波信号
distance = duration * 0.034 / 2; // 声速为340m/s,距离等于时间差乘以声速再除以2
return distance;
}
5. 完整代码
#include "stm32f1xx_hal.h"
void GPIO_Config(void);
void Send_Trigger_Pulse(void);
uint32_t pulseIn(uint16_t pin, uint8_t state, uint32_t timeout);
float Measure_Distance(void);
int main(void)
{
float distance;
HAL_Init();
GPIO_Config();
while (1)
{
distance = Measure_Distance();
printf("Distance: %.2fcm\n", distance);
HAL_Delay(1000);
}
}
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void Send_Trigger_Pulse(void)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
HAL_Delay(10);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
}
uint32_t pulseIn(uint16_t pin, uint8_t state, uint32_t timeout)
{
uint32_t start, end;
GPIO_PinState bit;
start = HAL_GetTick();
do {
end = HAL_GetTick();
if (end - start > timeout) return 0;
bit = HAL_GPIO_ReadPin(GPIOB, pin);
} while (bit != state);
start = HAL_GetTick();
do {
end = HAL_GetTick();
if (end - start > timeout) return 0;
bit = HAL_GPIO_ReadPin(GPIOB, pin);
} while (bit == state);
return end - start;
}
float Measure_Distance(void)
{
uint32_t duration;
float distance;
Send_Trigger_Pulse();
duration = pulseIn(GPIO_PIN_1, GPIO_PIN_SET, 1000);
distance = duration * 0.034 / 2;
return distance;
}
阅读全文