STM32超声波模块(HC-SR04\US015)测试程序-HAL库函数

STM32F103系列单片机HAL库的超声波模块测试程序

原理:
声波遇到障碍物会反射,而声波的速度已知,所以只需要知道发射到接收的时间差,就能轻松计算出测量距离,再结合发射器和接收器的距离,就能算出障碍物的实际距离。
在这里插入图片描述
超声波原理图
在这里插入图片描述
以HC-SR04硬件为例,端口为VCC、Trig、Echo、GND。

  • VCC–接STM32板子+5V;
  • GND–接STM32板子GND;
  • Trig–为触发控制信号输入,触发测距,给至少10us的高电平信号,模块自动发射8个40KHz的方波,自动检测是否有信号返回;
  • Echo–回响信号输出,有信号返回,通过IO口ECHO输出一个高电平,高电平持续时间就是超声波从发射到返回的时间。
    那用STM32怎么给端口信号呢?又是怎么获取信号呢?
    Trig端口为超声波模块的输入信号,也就是通过STM23一个端口推挽输出一个至少10us的高电平信号即可,利用delay_ms(20)实现;
    Echo端口为超声波模块的输出信号,也就是利用STM32端口捕获高电平时间,那么这个端口肯定是可以用做定时器的端口。
    通过以上分析,这里采用以下STM32端口
    在这里插入图片描述

    超声波模块硬件连接图
    定时器捕获原理:arr为自动重装载值,psc为时钟预分频数
    在这里插入图片描述
    当捕获不满一个时长的原理图
    在这里插入图片描述
    当捕获超过一个时长的原理图

部分程序
Trig程序

void Trig_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_GPIOA_CLK_ENABLE();           	//开启GPIOA时钟
    
    GPIO_Initure. Pin=GPIO_PIN_0;//PA8
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  	//推挽输出
    GPIO_Initure.Pull=GPIO_PULLDOWN;          	//下拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;    	 	//高速
	  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
	  HAL_GPIO_Init(GPIOA,&GPIO_Initure);
	
}

void CHL_capture(void)
{    
			TRIG1=1;
			delay_us(20);
			TRIG1=0;
}

Echo程序

#include "us015timer.h"
#include "led.h"
//  PA1---Echo     TIM2 CH2 

//TIM2  捕获初始化
TIM_HandleTypeDef TIMx_Handler;         //定时器3句柄

//定时器2通道1输入捕获配置
//arr:自动重装值(TIM2是16位的!!)
//psc:时钟预分频数
void TIM2_CHx_Cap_Init(u32 arr,u16 psc)
{  
    TIM_IC_InitTypeDef TIMx_CHyConfig;  
    
    TIMx_Handler.Instance=TIM2;                          //通用定时器2
    TIMx_Handler.Init.Prescaler=psc;                     //分频系数
    TIMx_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    //向上计数器
    TIMx_Handler.Init.Period=arr;                        //自动装载值
    TIMx_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频因子
   	TIMx_Handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;//使能自动重载
    HAL_TIM_IC_Init(&TIMx_Handler);						//初始化输入捕获时基参数
    
    TIMx_CHyConfig.ICPolarity=TIM_ICPOLARITY_RISING;    //上升沿捕获
    TIMx_CHyConfig.ICSelection=TIM_ICSELECTION_DIRECTTI;//映射到TI1上
    TIMx_CHyConfig.ICPrescaler=TIM_ICPSC_DIV1;          //配置输入分频,不分频
    TIMx_CHyConfig.ICFilter=0;                          //配置输入滤波器,不滤波
    HAL_TIM_IC_ConfigChannel(&TIMx_Handler,&TIMx_CHyConfig,TIM_CHANNEL_2);//配置TIM3通道3
	
    HAL_TIM_IC_Start_IT(&TIMx_Handler,TIM_CHANNEL_2);   //开启TIM2的捕获通道2,并且开启捕获中断
    __HAL_TIM_ENABLE_IT(&TIMx_Handler,TIM_IT_UPDATE);   //使能更新中断
	
	HAL_NVIC_SetPriority(TIM2_IRQn,2,0);    //设置中断优先级,抢占优先级2,子优先级0
    HAL_NVIC_EnableIRQ(TIM2_IRQn);          //开启ITM2中断通道  
}

//定时器2底层驱动,时钟使能,引脚配置
//此函数会被HAL_TIM_IC_Init()调用
//htim:定时器2句柄
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_TIM2_CLK_ENABLE();            //使能TIM2时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();			//开启GPIOA时钟
	
    GPIO_Initure.Pin=GPIO_PIN_1;            //PA1
    GPIO_Initure.Mode=GPIO_MODE_AF_INPUT; 	//复用推挽输入
    GPIO_Initure.Pull=GPIO_PULLDOWN;        //下拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);

    HAL_NVIC_SetPriority(TIM2_IRQn,2,0);    //设置中断优先级,抢占优先级2,子优先级0
    HAL_NVIC_EnableIRQ(TIM2_IRQn);          //开启ITM2中断通道  
}

//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.
//[5:0]:捕获低电平后溢出的次数
u8  TIM2CH2_CAPTURE_STA=0;							//输入捕获状态		    				
u16	TIM2CH2_CAPTURE_VAL;							  //输入捕获值(TIM2是16位)

//定时器2中断服务函数
void TIM2_IRQHandler(void)
{
	HAL_TIM_IRQHandler(&TIMx_Handler);				//定时器共用处理函数
}
 
//定时器更新中断(计数溢出)中断处理回调函数, 该函数在HAL_TIM_IRQHandler中会被调用,实现多个计数器满装载的计数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//更新中断(溢出)发生时执行
{
	if((TIM2CH2_CAPTURE_STA&0X80)==0)				//还未成功捕获上升沿
	{
		if(TIM2CH2_CAPTURE_STA&0X40)				//已经捕获到高电平了
		{
			if((TIM2CH2_CAPTURE_STA&0X3F)==0X3F)	//高电平太长了
			{
				TIM2CH2_CAPTURE_STA|=0X80;			//标记成功捕获了一次
				TIM2CH2_CAPTURE_VAL=0XFFFF;
			}else TIM2CH2_CAPTURE_STA++;
		}	 
	}		
}

//定时器输入捕获中断处理回调函数,该函数在HAL_TIM_IRQHandler中会被调用
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断发生时执行
{
	if((TIM2CH2_CAPTURE_STA&0X80)==0)				//还未成功捕获
	{
		if(TIM2CH2_CAPTURE_STA&0X40)				//捕获到一个下降沿 		
		{	  			
			TIM2CH2_CAPTURE_STA|=0X80;				//标记成功捕获到一次高电平脉宽
            TIM2CH2_CAPTURE_VAL=HAL_TIM_ReadCapturedValue(&TIMx_Handler,TIM_CHANNEL_2);//获取当前的捕获值.
			TIM_RESET_CAPTUREPOLARITY(&TIMx_Handler,TIM_CHANNEL_2);   //一定要先清除原来的设置!!
            TIM_SET_CAPTUREPOLARITY(&TIMx_Handler,TIM_CHANNEL_2,TIM_ICPOLARITY_RISING);//配置TIM2通道2上升沿捕获
		}else  										//还未开始,第一次捕获上升沿
		{
			TIM2CH2_CAPTURE_STA=0;					//清空
			TIM2CH2_CAPTURE_VAL=0;
			TIM2CH2_CAPTURE_STA|=0X40;				//标记捕获到了上升沿
			__HAL_TIM_DISABLE(&TIMx_Handler);      	//关闭定时器2
			__HAL_TIM_SET_COUNTER(&TIMx_Handler,0);
			TIM_RESET_CAPTUREPOLARITY(&TIMx_Handler,TIM_CHANNEL_2);   //一定要先清除原来的设置!!
			TIM_SET_CAPTUREPOLARITY(&TIMx_Handler,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING);//定时器2通道2设置为下降沿捕获
			__HAL_TIM_ENABLE(&TIMx_Handler);		//使能定时器2
		}		    
	}		
}
	

主函数

int main()
{
   
  	HAL_Init();                    	//初始化HAL库    
    Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72M
    delay_init(72);                 //初始化延时函数
	  uart_init(9600);				//初始化串口
    LED_Init();                     //初始化LED 
	  Trig_Init();
	  TIM2_CHx_Cap_Init(0xffff,7200-1);
    float len=0;
	   u32 time=0; 
	  
	while(1)
		{	u8 count=0;
			delay_ms(10);
			
					   CHL_capture();  //PAout(0)
				    if(TIM2CH2_CAPTURE_STA&0X80)           //成功捕获到了一次高电平
		        {
							time=TIM2CH2_CAPTURE_STA&0X3F; 
							time*=65536;		 	    	        //溢出时间总和
							time+=TIM2CH2_CAPTURE_VAL; 			//得到总的高电平时间
							len=time*1.7;
							if(len<20)
							LED0=0;
							else LED0=1;
							TIM2CH2_CAPTURE_STA=0;          //开启下一次捕获
							 }
							printf("LENGHT:%f CM\r\n",len);  //打印平均距离
							

     

    }
			
	}

程序下载链接(https://download.csdn.net/download/qq_42258981/12141380)

  • 12
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
引用提到了使用HAL库完成对HC-SR04超声波模块的距离测量。该库包括了超声波传感器的原理、STM32CUBEMX的配置以及程序的完善。使用这个库可以实现对超声波模块的距离测量功能。而引用中提到了HC-SR04超声波模块的接线方法,其中VCC接STM32板子的5V电源,GND接STM32板子的地,Trig是触发控制信号输入,用于触发测距,需要给至少10us的高电平信号,而Echo是回响信号输出,用于接收超声波发射后的回响信号,Echo输出的高电平持续时间就是超声波从发射到返回的时间。在STM32中,可以通过一个端口作为Trig端口,通过推挽输出一个至少10us的高电平信号进行触发;而可以选择另一个端口作为Echo端口,利用端口捕获高电平时间来获取回响信号。根据引用的分析,可以选择相应的STM32端口来实现这些功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [手把手教你,通过HAL库实现STM32超声波测距--以SR-04为例](https://blog.csdn.net/tangxianyu/article/details/121519637)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [HAL库实现定时器实现多个超声波HC-SR04)测距](https://download.csdn.net/download/XiaoCaiDaYong/33511071)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值