HC-SR04模块有4个管脚,分别是VCC、GND、Trij、Echo。
原理:
启动超声波模块需要对Trij管脚进行拉高操作然后延时至少10us之后在拉低,此时超声波模块才能启动,并开始计时。启动之后超声波模块的一个向外发送8次40Khz的声波,如果超声波接收到了声波返回的信号之后此时Echo会拉高并停止计时,最后通过声波在空气中的速度,就可以计算距离。
时序图:
超声波在空气中大概速度:
计算公式:距离=(速度*时间)/2
声波从发送到接收是距离的两倍,所以我们需要除以2。
CubeMX的配置
选择自己的芯片型号:STM32F407VE
选择外部高速时钟:
配置时钟树:
打开SYS选择下载方式:
配置管脚:
打开串口(可打开可不打开,可以查看实时数据)选择异步通信:
打开定时器:
生成程序:
代码:
main里的代码:
/* USER CODE BEGIN Includes */
#include "tim.h"
#include "stdio.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
int fputc(int ch, FILE *f)//重定向
{
while((USART1->SR & 0X40)==0);
USART1->DR = (uint8_t) ch;
return ch;
}
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
void for_delay_us(uint16_t nus)//微秒级延时(循环)
{
uint16_t i;
for(i=0;i<nus;i++){
__NOP();}
}
void Start(void) //启动超声波模块
{
HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,1); //拉高
for_delay_us(15); //15us延时
HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,0); //拉低
}
int Get(void)
{
return HAL_GPIO_ReadPin(Echo_GPIO_Port,Echo_Pin); //获得Echo的电平高低
}
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
void start(void)//开始计时
{
__HAL_TIM_SetCounter(&htim6,0); //清0开始计数
HAL_TIM_Base_Start_IT(&htim6); // 开启定时器更新中断
}
unsigned int get_stop(void)//获取停止之后的数据
{
unsigned int num,dta;
HAL_TIM_Base_Stop_IT (&htim6); //关闭定时器更新中断
num = __HAL_TIM_GetCounter(&htim6); //获得计数值
dta = (num*346)/20000; //cm为单位
return dta;
}
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_TIM6_Init();
/* USER CODE BEGIN 2 */
unsigned int dta;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{ Start(); //启动超声波模块
printf("超声波模块已启动\r\n");
while(!Get()); //当Echo返回0,等待,变为1继续
start();//开始计时
while(Get()); //当Echo为1计数并等待 ,变为0继续
dta = get_stop();
printf("测试距离为:%d cm\r\n",dta);
HAL_Delay(1000); //延时
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
结果: