1.软件准备
(1)编程平台:Keil5
(2)CubeMX
(3)XCOM(串口调试助手)
2.硬件准备
(1)某宝买的超声波模块
(2)F1的板子,本例使用经典F103C8T6
(3)ST-link 下载器
(4)USB-TTL模块
(5)杜邦线若干
3.模块资料
(1)模块简介:
超声波是振动频率高于20kHz的机械波。它具有频率高、波长短、绕射现象小、方向性好、能够成为射线而定向传播等特点。HC-SRO4是一款尺寸完全兼容老版本,增加UART和IIC功能的开放式超声波测距模块,默认条件下,软件与硬件完全兼容老版本HC-SRO4;可以通过电阻设置成UART或IIC模式。2CM盲区,4.5M典型最远测距,2.2mA作电流。采用升级解调芯片RCWL-9206,带UART与IIC功能MCU:使其外围更加简洁,工作电压更宽(3-5.5V),接口功能更多。
(2)模块参数:
①专业解调测距芯片RCWL-9206
②支持GPIO,UART与IIC三种模式接口
③2.2mA工作电流
④2cm最小盲区
⑤2cm-450cm的超宽测量范围
⑥工作温度:-10°C-70°c
⑦3V-5.5V宽电压供电
(3)工作原理
(4)本例程实现思路:
程序采用状态机编程,MCU给模块Trig引脚输出一个高电平脉冲–>模块发送脉冲信号–>定时器启动高电平输入捕获–>模块返回的高电平信号到达定时器开始计数–>返回信号变为低电平定时器停止计数–>得到定时器时间差–>根据公式计算距离
4.CubeMX配置
(1)芯片选择
(2)配置RCC、SYS、时钟树
配置RCC
配置SYS
配置时钟树
(3)配置GPIO
(4)配置串口1
(5)配置定时器
(6)开启定时器中断
(7)设置路径、生成代码工程
5、Keil5代码
(1)勾选Use MicroLIB
(2)创建SR04.c和SR04.h文件
(3)添加上述的SR04.c文件进工程
——————上述两步参考之前系列教学步骤,在此不再赘述(点击跳转)
(4)SR04.c和SR04.h代码
SR04.h
#ifndef __SR04_H
#define __SR04_H
#include "main.h"
#include "tim.h"
#include "stdio.h"
#define TRIG_H HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_SET)
#define TRIG_L HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_RESET)
void delay_us(uint32_t us);
void SR04_GetData(void);
#endif
SR04.c
#include "SR04.h"
float distant; //测量距离
uint32_t measure_Buf[3] = {0}; //存放定时器计数值的数组
uint8_t measure_Cnt = 0; //状态标志位
uint32_t high_time; //超声波模块返回的高电平时间
//===============================================读取距离
void SR04_GetData(void)
{
switch (measure_Cnt){
case 0:
TRIG_H;
delay_us(30);
TRIG_L;
measure_Cnt++;
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); //启动输入捕获 或者: __HAL_TIM_ENABLE(&htim5);
break;
case 3:
high_time = measure_Buf[1]- measure_Buf[0]; //高电平时间
printf("\r\n----高电平时间-%d-us----\r\n",high_time);
distant=(high_time*0.034)/2; //单位cm
printf("\r\n-检测距离为-%.2f-cm-\r\n",distant);
measure_Cnt = 0; //清空标志位
TIM2->CNT=0; //清空计时器计数
break;
}
}
//===============================================us延时函数
void delay_us(uint32_t us)//主频72M
{
uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
while (delay--)
{
;
}
}
//===============================================中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//
{
if(TIM2 == htim->Instance)// 判断触发的中断的定时器为TIM2
{
switch(measure_Cnt){
case 1:
measure_Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING); //设置为下降沿捕获
measure_Cnt++;
break;
case 2:
measure_Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1); //停止捕获 或者: __HAL_TIM_DISABLE(&htim5);
measure_Cnt++;
}
}
}
(5)usrat.c代码添加
/* USER CODE BEGIN 0 */
#include "stdio.h"
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
/*********************************************************
*
*重定义 fputc 函数
*
*********************************************************/
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit (&huart1 ,(uint8_t *)&ch,1,HAL_MAX_DELAY );
return ch;
}
/* USER CODE END 1 */
(6)main函数
#include "SR04.h"
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_TIM2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
SR04_GetData( );
HAL_Delay(1500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
6.接线图及效果
10cm测距
本例程源码下载:点击跳转
转自:
https://blog.csdn.net/lwb450921/article/details/123670786