STM32F103与超声波测距模块

      现在网上卖的超声波测距模块非常多,我买了一块US-020型号的模块玩了一下,现将应用方法分享一下。我用的硬件是STM32F103RCT6,软件是MDK。

04.jpg

       模块除电源和地引脚外,有Trig引脚和Echo引脚,Trig给一个大于10us的高电平,超声波模块就会发射超声波。Echo输出高电平计时脉冲,高电平时间为发送到接收的时间,是测量距离的2倍传输时间。因此我们读取Echo的时间后,要除以2计算出来才是正确的。

一、设置定时器

   我使用的晶振是8M,设置CPU工作频率为72M,定时器设置如下:


#include "timer.h"
TIM_HandleTypeDef    TimHandle;
void timer2_init()
{ 
uint32_t uwPrescalerValue = 0; 
uwPrescalerValue = (uint32_t)(SystemCoreClock / 100000) - 1;   
//计时脉冲频率为100000Hz  
/* Set TIMx instance */  
TimHandle.Instance = TIM2; 
TimHandle.State=HAL_TIM_STATE_RESET; 
__HAL_RCC_TIM2_CLK_ENABLE();
  
TimHandle.Init.Period            = 10;     
//10个计时脉冲为一个计时周期,也就是0.1ms  
TimHandle.Init.Prescaler         = uwPrescalerValue; 
TimHandle.Init.ClockDivision     = 0;
TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
TimHandle.Init.RepetitionCounter = 0;
if
(HAL_TIM_Base_Init(&TimHandle) != HAL_OK) 
{   
while(1);  
}

二、设置引脚

设置驱动Trig的引脚与读取Echo的引脚,代码如下:

void ChaoSheng_init(void)
{  
static GPIO_InitTypeDef  GPIO_InitStruct;
 __HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;  
GPIO_InitStruct.Pull  = GPIO_PULLUP;  
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = TRIG_PIN; 
HAL_GPIO_Init(ChaoSheng_Port, &GPIO_InitStruct);
 
GPIO_InitStruct.Mode  = GPIO_MODE_INPUT;  
GPIO_InitStruct.Pull  = GPIO_PULLUP;  
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 
GPIO_InitStruct.Pin = ECHO_PIN; 
HAL_GPIO_Init(ChaoSheng_Port, &GPIO_InitStruct); 
}
/***********************发Trig脉冲************************/
void Start_Trig(void)
{
HAL_GPIO_WritePin(ChaoSheng_Port, TRIG_PIN, GPIO_PIN_SET);
}
/***********************Trig脉冲停止************************/
void Stop_Trig(void)
{
HAL_GPIO_WritePin(ChaoSheng_Port, TRIG_PIN, GPIO_PIN_RESET);
}
 
/***********************计算距离************************/
int get_dis(int test_time)
{
int dis=0;
dis=340*test_time/200;
return dis;
}

三、main函数

int main(void)
{  
HAL_Init();   
/* Configure the system clock to 72 MHz */  
SystemClock_Config(); 
ChaoSheng_init(); 
lcd_init();    
//因我是在LCD上显示结果,所以进行LCD初使化
 
lcd_clear();  
timer2_init();   
//定时器初使化
while (1)    
//测距死循环 
{   
Start_Trig();      
delay_ms(1);   
Stop_Trig();  
while(HAL_GPIO_ReadPin(GPIOA, ECHO_PIN)!=GPIO_PIN_SET); 
if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)     
{       
while(1);    
}    
HAL_TIM_IRQHandler(&TimHandle);   
while(HAL_GPIO_ReadPin(GPIOA, ECHO_PIN)==GPIO_PIN_SET);   
HAL_TIM_Base_Stop_IT(&TimHandle); 
delay_ms(1);  
timer_buf[test_time]=timer01; 
test_time++; 
timer01=0; 
delay_ms(100);
if(test_time>10)     
//测试10次,然后把10次结果去掉两个最大值与两个最小值后求平均值
{ 
dis01=get_dis(data_average(timer_buf));   
//用冒泡法先排序,然后去掉两个最大值与两个最小值后求平均值,并计算距离  
int_to_ascii(dis01,0,0,outbuf);  
lcd_clear();  
lcd_display(0,0,outbuf);     
timer01=0;    
test_time=0;     
}
}
}


0 条评论

目前没有人发表评论

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。