基于STM32超声波测距

整个工程代码见文末

2019年7月26日
做小车的第5天。
今天我又学习了一个新的知识:超声波测距。
超声波测距(超声波测距模块US-025)的基本原理如下:
Trig端:向此管脚输入一个超过10us以上的高电平,可触发模块测距
Echo端:当测距结束时,此管脚会输出一个高电平,电平宽度为超声波往返时间之和。

只需要在Trig管脚输入一个10US以上的高电平,系统便可发出8个40KHZ的超声波脉冲,然后检测回波信号。当检测到回波信号后,通过Echo管脚输出。
根据Echo管脚输出高电平的持续时间可以计算距离值。即距离值为:(高电平时间*340m/s)/2

当测量距离超过US-025/US-026的测量范围时,仍会通过Echo管脚输出高电平的信号,高电平的宽度约为66ms。

代码大致如下:
/*******************************************************.h函数********/
#define TRIG_Send PAout(6) //输出端口为PA6
#define ECHO_Reci PAin(7) //输入端口为PA7

float Senor_Using(void);
void TIM3_Int_Init();

/**********************************************.c函数/
uint overcount=0; //记录定时器溢出次数
void TIM3_Int_Init()
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/*****************************************************************
PA6为输出端 PA7为输入端*****************/
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//设置为推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_7;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//定时器3初始化
TIM_TimeBaseStructure.TIM_Period = 999; //设置自动重转载值为999
TIM_TimeBaseStructure.TIM_Prescaler =71; //设置预分频系数
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );//使能制定TIM3中断,允许更新中断
//中断设置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

TIM_Cmd(TIM3, DISABLE);
}
//下面写测距函数
float Senor_Using(void) //单精度数据类型
{
float length=0,sum=0;
u16 tim;
unsigned int i=0;
//测五次数据计算一次平均值
while(i!=5)
{
PAout(6)=1; //拉高信号,作为触发信号
delay_us(20); //高电平信号超过10us
PAout(6)=0; //等待回响信号
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==RESET);
//回响信号到来,开启定时器计数
TIM_Cmd(TIM3,ENABLE);
i+=1; //每收到一次回响信号+1,收到5次就计算均值
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==SET);//回响信号消失
TIM_Cmd(TIM3,DISABLE);//关闭定时器
tim=TIM_GetCounter(TIM3); //获取计TIM3数寄存器中的计数值
length=(tim+overcount*1000)/58.0; //通过回响信号计算距离
sum=length+sum;
TIM3->CNT=0; //将TIM3计数寄存器的计数值清零
overcount=0; //中断溢出次数清零
delay_ms(100);
}
length=sum/5;
return length; //距离作为函数返回值
}

void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3,TIM_IT_Update)!= RESET) //检查是否发生TIM3中断
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清楚中断更新标志
overcount++;
}
}
/*************************main/
int main(void)
{
float length;
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(9600);
TIM3_Int_Init();
while(1)
{
length = Senor_Using(); //调用测距函数
printf(“距离为:%.3fcm\n”,length);
delay_ms(1000);
}
}
超声波测距模块原理图以及如下:在这里插入图片描述串口接收到的数据

在这里插入图片描述
代码链接: link.
提取码:gjfx

  • 55
    点赞
  • 309
    收藏
    觉得还不错? 一键收藏
  • 25
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值