一、准备工作:
有关CUBEMX的初始化配置,参见我的另一篇blog:【STM32+HAL】CUBEMX初始化配置
二、所用工具:
1、芯片:STM32F103C8T6
2、CUBEMX配置软件
3、超声波模块HC-SR04
三、实现功能:
测量超声波模块与障碍物之间距离(2-600cm)
四、HAL配置步骤:
1、打开TIM3输出触发信号
每隔一定时间(70ms)输出高电平,并持续一定时间(10us+)
2、开启TIM2定时器输入捕获功能
周期设为1us(72M / 72)
3、中断配置(不唯一)
至此,CUBEMX配置完成
五、KEIL填写代码
1、接线
接线:
VCC -> 3.3V
Trig -> PB14
Echo -> PA0-WKUP
GND ->GND
2、变量定义
#define TRIG_ON HAL_GPIO_WritePin(GPIOB, TRIG_Pin, GPIO_PIN_SET)
#define TRIG_OFF HAL_GPIO_WritePin(GPIOB, TRIG_Pin, GPIO_PIN_RESET)
uint32_t capture_Buf[4] = {0};
uint8_t capture_Cnt = 0;
uint32_t high_time;
double distance=0;
3、us级延时函数定义
void delay_us(uint32_t us)//主频72M
{
uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
while (delay--);
}
4、初始化程序
TRIG_OFF;
HAL_TIM_Base_Start_IT(&htim3);
printf("Hello World!\r\n");
HAL_Delay(300);
5、定时器中断(70ms为一个周期)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
UNUSED(htim);
if ( htim -> Instance == TIM3 ){
TRIG_ON;
delay_us(15); //持续至少10us
TRIG_OFF;
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
}
}
6、定时器输入捕获
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(TIM2 == htim->Instance){
switch(capture_Cnt){
case 0: //low level
capture_Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);
capture_Cnt++;
break;
case 1: //high level
capture_Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1);
capture_Cnt = 0;
// __HAL_TIM_SET_COUNTER(&htim2,0); //清零会有问题
high_time = capture_Buf[1]- capture_Buf[0];
distance=high_time*0.017; //速度0.034cm/us,计算出的距离要除以2,distances的单位是cm
break;
default: break;
}
}
}
六、原理讲解
STM32系列(HAL库)——F103C8T6通过HC-SR04超声波模块实现测距
HC-SR04超声波模块的使用(stm32f103c8t6/HAL)(超详细)
七、源码提供
八、总结
超声波模块仅在测量物体表面光滑平整的前提下精度较高,否则测量数据偏移量较大