一、超声波测距原理
》》超声波测距原理是在超声波发射装置发出超声波,在发射超声波的同时开始计时,超声波在空气中传播,在传播的时刻碰到障碍物,就会返回一个信号给超声波接收器,超声波接收器接收到信号后立即停止计时,这时候会有一个时间t,而超声波在空气中传播的速度为340m/s,通过公式s=340 x t / 200,即可计算出待测距离是多少。(公司用的是HC-SR04,可提供2cm-400cm的非接触式测距功能)
1、采用单片机I/O口TRIG触发测距,给定至少10us的高电平;
2、模块自动发送8个40khz的方波,自动检测是否有信号返回;
3、有信号返回,通过I/O口ECHO输出一个高电平,高电平持续的时间(用定时器进行定时)就是波从发射到返回的时间。测试距离=(高电平时间 x 声速(340m/s))/2;
二、HC-SR04超声波测距模块工作原理
1、采用I/O口触发方式测距,通过单片机发出至少10us的高电平信号到超声波模块的Trig引脚,用于触发超声波模块工作;
2、模块会自动发送8个40KHz的方波信号,自动检测是否有信号返回;
3、有信号返回,通过Echo引脚连接单片机的I/O口输出一高电平,高电平持续时间就是超声波从发射到返回的时间;
4、声音在空气中的传播速度为340米/秒,即可计算出所测的距离;
三、具体代码测距方式
1、定时器方式
2、延时方式
四、测距离公式
1、正常的计算距离的公式
测试距离=[ 高电平时间 x 速度(340m/s)/2 ](除以2表示,从发出到接收)
测量单位:测量距离(米)、速度(米/秒)、高电平时间(秒)
2、将单位改变后的测距离的公式
测试距离=[ (高电平时间us/1000000)x 340 / 2 x 100 ] =高电平时间us/58
测量单位:测量距离(厘米)、速度(厘米/秒)、高电平时间(微秒)
五、HC-SR04模块(工作电压:DC 5V)
该模块包括超声波发射器、接收器与控制电路
六、注意事项
1、此模块不宜带电连接,若要带电连接,则先让模块的GND端接地,否则会影响模块的正常工作;
2、测距时,被测物体的面积不少于0.5平方米且平面要求平整,否则会影响测量的结果;
七、编程思路
1、HC-SR04超声波发出8个40KHz的方波,然后再遇到障碍物通过ECHO给单片机返回一个高电平,从触发HC-SR04工作开始计时,到ECHO返回高电平停止计时,这段时间计为t;
2、然后通过公式就可以算出此时的距离s;
main函数: #include "stm32f10x.h" #include "delay.h" #include "hc_sr04.h" #include "stdio.h" #include "usart.h" u8 count=0; int main() { delay_init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); HC_SR04_Init(); NVIC_Config(); uart_init(9600); Time2_Init(20,3600);//1ms中断1次 // while(1) // { hc_sr04_calculate(); count = 0; delay_ms(1000); printf("HC-SR04测距计算完成!overn"); // } } hc_sr04.c源文件: #include"stm32f10x.h" #include"hc_sr04.h" #include"stdio.h" //hc_sr04引脚初始化 void HC_SR04_Init(void)//初始化hc_sro4的连接引脚 { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//开启GPIOB时钟 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//将hc_sr04的Trig引脚连接到单片机的PB5引脚上,单片机给HC_SR04提供至少10us的脉冲 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;//将hc_sr04的Echo引脚连接到单片机的PB6引脚上,HC_SR04反馈高电平信号给单片机 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); } //通用定时器Tim2初始化 void Time2_Init(u32 Period , u32 Prescaler) { TIM_TimebaseInitTypeDef TIM_TimebaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启定时器TIM2的时钟 TIM_TimebaseStructure.TIM_Period = Period;//自动重装载寄存器的值 TIM_TimebaseStructure.TIM_Prescaler = Prescaler;//时钟预分频数 TIM_TimebaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//采样分频 TIM_TimebaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数 TIM_TimebaseInit(TIM2,&TIM_TimebaseStructure); TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除溢出中断标志位 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//TIM2中断使能 // TIM_Cmd(TIM2,ENABLE);//使能定时器Tim2 } //NVIC配置 void NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;//中断通道号配置为TIM2 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//无占先优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//无副优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断使能 NVIC_Init(&NVIC_InitStructure);//NVIC初始化 } //给hc_sr04一个启动信号 void hc_sr04_start(void) { Trig=1; delay_us(20); Trig=0; } //计算hc_sr04测出来的值 void hc_sr04_calculate(void) { float temp; while(Echo==1); hc_sr04_start();//启动hc_sr04超声波传感器 while(Echo==0); printf("收到20us的脉冲,开始发送8个40KHz的方波信号!rn"); delay_ms(500); printf("hc_sr04正在开始测距.......rn"); TIM_SetCounter(TIM2,0);//清空计数器 TIM_Cmd(TIM2,ENABLE);//开启定时器 while(Echo==1);//如果hc_sr04返回低电平说明还未检测到前面有障碍物,就一直执行该程序 TIM_Cmd(TIM2,DISABLE);//停止计数 temp=TIM_GetCounter(TIM2)*340/(2*1000); printf("距离:%6.2fmn",temp); } hc_sr04.h头文件: #ifndef _HC_SRO4_H #define _HC_SR04_H #include "stm32f10x.h" #include "delay.h" #define Trig PBin(5) #define Echo PBout(6) void HC_SR04_Init(void); void Time2_Init(u32 Period , u32 Prescaler); void NVIC_Config(void); void hc_sr04_start(void); void hc_sr04_calculate(void); void delay_init(); void uart_init(u32 bound); #endif
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)