STM32 HAL/STD库驱动HC-SR04测距
- ✨说明:本文不介绍HC-SR04原理。
-
🌿工程案例一:HAL库实现方法比较简易,只需配置2个IO引脚:一个配置为输入,一个配置为输出即可。
-
🌿工程案例二:基于标准库例程,是使用定时器3,输出通道比较模式:TIM_OCMode_PWM1和输入通道捕获上升沿检测实现。
-
🌿工程案例三:基于HAL库实现方法实现,使用定时器2(TIM2),输入捕获功能实现。(使用的是STM32F4系列)
-
- 🌿工程案例四:基于HAL库实现方法实现,使用外部中断 +定时器2(TIM2)计数,实现测距。
-
🌼HC-SR04
📓案例二中标准库驱动函数
- 👉🏻使用的是正点原子资料中的标准库工程模版
- 📝
stm32f10x_HC-SR04.c
#include "stm32f10x_HC-SR04.h"
extern void EnableHCSR04PeriphClock(void);
static void initMeasureTimer() {
RCC_ClocksTypeDef RCC_ClocksStatus;
RCC_GetClocksFreq(&RCC_ClocksStatus);
uint16_t prescaler = RCC_ClocksStatus.SYSCLK_Frequency / 1000000 - 1; //1 tick = 1us (1 tick = 0.165mm resolution)
TIM_DeInit(US_TIMER);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_Prescaler = prescaler;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(US_TIMER, &TIM_TimeBaseInitStruct);
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_OCStructInit(&TIM_OCInitStruct);
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = 15; //us
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC3Init(US_TIMER, &TIM_OCInitStruct);
TIM_ICInitTypeDef TIM_ICInitStruct;
TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStruct.TIM_ICFilter = 0;
TIM_PWMIConfig(US_TIMER, &TIM_ICInitStruct);
TIM_SelectInputTrigger(US_TIMER, US_TIMER_TRIG_SOURCE);
TIM_SelectMasterSlaveMode(US_TIMER, TIM_MasterSlaveMode_Enable);
TIM_CtrlPWMOutputs(US_TIMER, ENABLE);
TIM_ClearFlag(US_TIMER, TIM_FLAG_Update);
}
static void initPins() {
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = US_TRIG_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(US_TRIG_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = US_ECHO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(US_ECHO_PORT, &GPIO_InitStructure);
}
void InitHCSR04() {
EnableHCSR04PeriphClock();
initPins();
initMeasureTimer();
}
int32_t HCSR04GetDistance() {
(US_TIMER)->CNT = 0;
TIM_Cmd(US_TIMER, ENABLE);
while(!TIM_GetFlagStatus(US_TIMER, TIM_FLAG_Update));
TIM_Cmd(US_TIMER, DISABLE);
TIM_ClearFlag(US_TIMER, TIM_FLAG_Update);
return (TIM_GetCapture2(US_TIMER)-TIM_GetCapture1(US_TIMER))*165/1000;
}
- 📝
stm32f10x_HC-SR04.h
#ifndef __STM32F10X_HC_SR04_H_
#define __STM32F10X_HC_SR04_H_
#include "stm32f10x.h"
#define US_TIMER TIM3
#define US_TRIG_PORT GPIOB
#define US_TRIG_PIN GPIO_Pin_0 //TIM Ch3 (trig output)
#define US_ECHO_PORT GPIOA
#define US_ECHO_PIN GPIO_Pin_6 //TIM Ch1 (echo input)
#define US_TIMER_TRIG_SOURCE TIM_TS_TI1FP1
/**
* How to use this driver:
* 1. Implement EnableHCSR04PeriphClock function and turn on clock for used peripherals
* ex:
* void EnableHCSR04PeriphClock() {
* RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
* RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
* RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
* }
* 2. Call InitHCSR04();
* 3. Get distance (in mm) using HCSR04GetDistance function.
* Value lower than zero means no echo received (distance >3m)
* Measuring takes about 65ms
*
* If necessary, change defines above, but be careful, US_ECHO_PIN must be tim ch1
* and US_TRIG_PIN must be ch3 or ch4. In case of ch4 change TIM_OC3Init into TIM_OC4Init in stm32f10x_HC-SR04.c file
*/
/**
* Implement this function. See instruction at the top of this file.
*/
void EnableHCSR04PeriphClock(void);
/**
* Initialization of HCSR04's peripherals
*/
void InitHCSR04(void);
/**
* Measure distance and get value in mm. Lower than 0 means no echo signal: distance more than ~3m.
*/
int32_t HCSR04GetDistance(void);
#endif /* STM32F10X_HC_SR04_H_ */
- 📝main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "stm32f10x_HC-SR04.h"
void EnableHCSR04PeriphClock() {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);