完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1 工作原理
使用超声波模块之前,先了解其IO口和工作原理: 1.1 IO说明 VCC: 供5V电源 GND: 为地线 TRIG: 触发控制信号输入 ECHO: 回响信号输出 1.2 基本工作原理: 认真看好以下工作原理,后面的代码就是基于工作原理来实现的。 (1)采用IO口TRIG触发测距,给最少10us的高电平信号。 (2)模块自动发送8个40khz的方波,自动检测是否有信号返回; (3)有信号返回, 通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。 测试距离=(高电平时间*声速(340M/S))/2 时序图: 2 程序编写 2.1 外设配置 根据两个信号引脚来配置两个单片机的IO口 trig: 需要产生一个10us高电平, 配置为推挽输出; echo: 等待高电平脉冲并测量其脉冲宽度, 配置为下拉输入 测量echo的高电平持续的时间,需要用到定时器, 因此配置一个定时器,用来计时 void UltrasonicWave_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIOB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // 对应trig引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,GPIO_Pin_1); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // 对应echo引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入 GPIO_Init(GPIOB, &GPIO_InitStructure); //定时器初始化,分频系数为71,则频率为1MHZ,每个计数为1us,(频率越高越精确) //重装载值为65535,溢出时间为1us*65536= 65.536ms=0.065536s //一个计数周期可以测距 0.065536s * 340m/s / 2 = 11.14112m TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 71; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // } 2.2 测距函数 根据工作原理 : (1)采用IO口TRIG触发测距,给最少10us的高电平信号。 /***** 启动超声波 *****/ void UltrasonicWave_StartMeasure(void) { GPIO_SetBits(GPIOB, GPIO_Pin_1); //拉高PB1电平 delay_us(20); //持续20us GPIO_ResetBits(GPIOB, GPIO_Pin_1); //拉低PB1电平 } (2)有信号返回, 通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。 测试距离=(高电平时间*声速(340M/S))/2 /***** 测距 *****/ float UltrasonicWave_Measure(void) // { while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==1);//echo为高电平时,则等待至低电平,才启动超声波 UltrasonicWave_StartMeasure(); //启动超声波 while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10) == 0);//等待echo的高电平到来 TIM_SetCounter(TIM2,0); //清零计数器 TIM_Cmd(TIM2, ENABLE); //使能定时器2,开始计数 while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10) == 1);//等待echo的高电平结束 TIM_Cmd(TIM52, DISABLE); //失能定时器2,截止计数 return (TIM_GetCounter(TIM2))/1000000*340/2 *100; //此处单位转换为cm } 2.3 测距 int main() { float distance; UltrasonicWave_Init(void);//初始化 delay_init(); while(1) { distance = UltrasonicWave_Measure(void); //完成测距 delay_ms(60);//建议测量周期为 60ms以上, 以防止发射信号对回响信号的影响。 printf("distance:%5.2f ",distance);//打印到串口 } } 还可以使用中断方式进行测距, 大致框架如下, 有兴趣自行研究 //先开启对应引脚双边沿触发中断, 中断服务函数大致如下 float Distance; void EXTI15_10_IRQHandler(void) { if(//发生中断) { if(//上升沿) { TIM_SetCounter(TIM2,0); //清零计数器 TIM_Cmd(TIM2, ENABLE); //使能定时器2,开始计数 } if(//下降沿) { TIM_Cmd(TIM52, DISABLE); //失能定时器2,截止计数 Distance=(TIM_GetCounter(TIM2))/1000000*340/2 *100;//此处单位转换为cm } } EXTI_ClearITPendingBit(EXTI_Line10); //清除中断标志 } //主函数 ```c extern float Distance; int main() { UltrasonicWave_Init(void);//初始化 while(1) { UltrasonicWave_StartMeasure();//启动超声波 delay_ms(60);//建议测量周期为 60ms以上, 以防止发射信号对回响信号的影响。 //Distance 在中断服务函数中被重新赋值 printf("Distance:%5.2f ",Distance);//打印到串口 } } 以上超声波模块的使用一次记录,欢迎一起讨论 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1376 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1368 浏览 1 评论
791 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
568 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1410 浏览 2 评论
1762浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
489浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
422浏览 3评论
415浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
391浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-9-30 14:41 , Processed in 0.876716 second(s), Total 74, Slave 59 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号