- HAL库
- STM32F103C8T6主控芯片
- HC-SR04超声波测距模块
参考文章,十分感谢原作者 手把手教你,通过HAL库实现STM32的超声波测距–以SR-04为例
工程源码
工程代码
基本配置
- 配置sys
 - 配置RCC

- 配置USART 用来串口输出,注意波特率
 - 配置时钟,将超声波测距模块的ECHO引脚设置为PB11,通道4,计数值和模式如下
 - 配置时钟

代码编写
- time.c 在
/* USER CODE BEGIN 1 */ 处编写,防止重新配置芯片的时候覆盖写好的代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if((TIM2CH2_CAPTURE_STA & 0x80)==0)
{
if(TIM2CH2_CAPTURE_STA & 0x40)
{
if((TIM2CH2_CAPTURE_STA & 0x3F) == 0x3F)
{
TIM2CH2_CAPTURE_STA |= 0X80;
TIM2CH2_CAPTURE_VAL = 0XFFFF;
}
else
TIM2CH2_CAPTURE_STA ++;
}
}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if((TIM2CH2_CAPTURE_STA & 0X80) == 0)
{
if(TIM2CH2_CAPTURE_STA & 50X40)
{
TIM2CH2_CAPTURE_STA |= 0X80;
TIM2CH2_CAPTURE_VAL = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_4);
TIM_RESET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_4);
TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_4,TIM_ICPOLARITY_RISING);
}
else
{
TIM2CH2_CAPTURE_STA = 0;
TIM2CH2_CAPTURE_VAL = 0;
TIM2CH2_CAPTURE_STA |= 0X40;
__HAL_TIM_DISABLE(&htim2);
__HAL_TIM_SET_COUNTER(&htim2,0);
TIM_RESET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_4);
TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_4,TIM_ICPOLARITY_FALLING);
__HAL_TIM_ENABLE(&htim2);
}
}
}
2 . 给TRIG引脚一个不小于10us的高电平,然后重新置为低电平,原理如下  gpio.c
void CHL_capture(void)
{
uint32_t i;
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET);
for(i=0;i<72*15;i++)
__NOP();
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET);
}
- main.c
1、串口打印函数
#ifdef __GNUC__
#define PUTCHAR_PROTOTYOE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYOE
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
2、定义变量
float len = 0;
uint32_t time = 0;
extern uint8_t TIM2CH2_CAPTURE_STA;
extern uint16_t TIM2CH2_CAPTURE_VAL;
3、启动定时器
printf("status----");
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_4);
__HAL_TIM_ENABLE_IT(&htim2,TIM_IT_UPDATE);
4、while函数
while (1)
{
HAL_Delay(1000);
CHL_capture();
if(TIM2CH2_CAPTURE_STA & 0X80)
{
time = TIM2CH2_CAPTURE_STA & 0X3f;
time *= 65536;
time += TIM2CH2_CAPTURE_VAL;
len = time * 342.62*100/2000000;
TIM2CH2_CAPTURE_STA = 0;
}
printf("length: %f cm\r\n",len);
}
可能遇到的问题
1、len一直为0,检查代码是否编写错误,接线是否正确 2、不能输出float  4、len有输出,但是一直不变,将vcc引脚的接到5v而不是3.3v 5、串口打印没有输出原因可能有两个
- main.c或者tim.c中没有包含头文件#include <stdio.h>
- RXD和TXD接线接反
|