超声波(HC-SR04)
1、
2、工作流程
①单片机引脚触发Trig测距,给至少10us的高电平
②模块自动发送8个40khz的方波,自动检测是否有信号返回
③有信号返回,通过IO口输出高电平,并单片机ji’shu’an2高电平的持续时间
④超声波从发射到返回的时间
测量距离=(高电平的时间*340m/s)/2 (因为声波一去一回,两倍的距离所以要除以2)
3、涉及单片机主要模块:输入捕获
(1)主要代码如下:
#include "HC_SRO4.h"
uint32_t HC_SRO4Val;//储存没到65535的值
uint32_t count=0;//进入更新中断的次数
uint16_t edge=0;//上升沿标志位
uint32_t startFlag;//开始中断标志位
uint32_t sr04_Over=0;//测量完成标志位//内部函数的声名
uint32_t calculate(void);
void HC_SRO4Start(void);//利用GPIO模拟strig信号
void HC_SRO4Start(void)
{uint32_t i;HAL_GPIO_WritePin(GPIO_Trig, PIN_Trig, GPIO_PIN_SET);for(i=0;i<72*40;i++)__NOP();HAL_GPIO_WritePin(GPIO_Trig, PIN_Trig, GPIO_PIN_RESET);
}//距离计算函数
//测量距离=(高电平时间*声速(340M/s))/2
//340mm/ms;340mm/1000us=0.34mm/us;
uint32_t calculate(void)
{ uint32_t res;//测量结果承接uint32_t hTime;hTime=count*65535+HC_SRO4Val; //usres=(hTime*0.034)/2;//cmreturn res;
}//超声波的各类初始化函数
void HC_SRO4_Init(void)
{HAL_TIM_IC_Start_IT(&HC_SRO4_HTIM,HC_SRO4_CHANNEL);//使能定时器中断__HAL_TIM_ENABLE_IT(&HC_SRO4_HTIM, TIM_IT_UPDATE);//使能定时器更新中断HC_SRO4Start();
}//结果输出函数
uint64_t HC_SRO4_result(void)
{uint32_t result;//测量结果承接if(sr04_Over){sr04_Over=0;count=0;result=calculate();HC_SRO4Start();}return result;
}//更新中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==HC_SRO4_TIM){if(startFlag==1){ if(count>0x3f)//超时判断{startFlag=0;//计数中断结束TIM_RESET_CAPTUREPOLARITY(&HC_SRO4_HTIM, HC_SRO4_CHANNEL);//清除原来的设置TIM_SET_CAPTUREPOLARITY(&HC_SRO4_HTIM,HC_SRO4_CHANNEL, TIM_ICPOLARITY_RISING );//将其变为上升沿捕获,因}else {count++;//记录溢出中断的次数}}}}//输入捕获中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==HC_SRO4_TIM){if(edge==1){startFlag=0;//计数中断结束edge=0;
// HC_SRO4Val=0;sr04_Over=1;//高电平时间结束标志位HC_SRO4Val=HAL_TIM_ReadCapturedValue(&HC_SRO4_HTIM,HC_SRO4_CHANNEL);//将缓冲区多余的值记录下来TIM_RESET_CAPTUREPOLARITY(&HC_SRO4_HTIM, HC_SRO4_CHANNEL);//清除原来的设置TIM_SET_CAPTUREPOLARITY(&HC_SRO4_HTIM,HC_SRO4_CHANNEL, TIM_ICPOLARITY_RISING );//将其变为上声沿捕获,因为已经计数完了,把 它还原回原样}else{startFlag=1;//计数中断开始edge=1;//上升后标志位__HAL_TIM_SET_COUNTER(&HC_SRO4_HTIM,0);//清除原来的计数值TIM_RESET_CAPTUREPOLARITY(&HC_SRO4_HTIM, HC_SRO4_CHANNEL);//清除原来的设置TIM_SET_CAPTUREPOLARITY(&HC_SRO4_HTIM,HC_SRO4_CHANNEL, TIM_ICPOLARITY_FALLING );//将其变为下降沿捕获 }}}
(2)其头文件
#ifndef _HC_SRO4_H
#define _HC_SRO4_H
#include "main.h"
#include "time.h"
/* 注意事项
1、记得要开定时器中断
2、输入捕获通道记得打开
3、配置一个GPIO口作为Trig
4、PSC配置成72-1
5、计数配置(ARR)65535
*/extern TIM_HandleTypeDef htim2;
#define HC_SRO4_HTIM htim2
#define HC_SRO4_TIM TIM2
#define HC_SRO4_CHANNEL TIM_CHANNEL_1
#define GPIO_Trig GPIOA
#define PIN_Trig GPIO_PIN_4//用户调用函数
void HC_SRO4_Init(void);//超声波初始化函数
uint32_t HC_SRO4_result(void);//返回测量结果函数#endif
(3)调用方法
将这两个函数写到main函数里
void HC_SRO4_Init(void);//main函数里
uint32_t HC_SRO4_result(void);//main函数的while循环里