这个是超声波测距的代码,可以添加stm32程序中,并且有测距的组件就可以使用了。
还附加有原理讲解图文word
超声波测距.7z
(676.27 KB, 售价: 1 E币)
HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。像智能小车的测距以及转向,或是一些项目中,常常会用到。智能小车测距可以及时发现前方的障碍物,使智能小车可以及时转向,避开障碍物。 HC-SR04基本工作原理: (1)采用IO口TRIG触发测距,给最少10us的高电平信呈。 (2)模块自动发送8个40khz的方波,自动检测是否有信号返回; (3)有信号返回, 通过IO口ECHO输出一个高电平, 高电平持续的时间就是超声波从发射到返回的时间。 测试距离=(高电平时间*声速(340M/S))/2。 程序编写思路是:1、配置好使用到的GPIO以及定时器; 2、给模块TRIG端口发送大于10us的高电平信号,当收、收到ECHO回响信号是,打开定时器开始定时; 3、当回响信号消失,关闭定时器; 4、通过定时器定时时间来确定距离。 先由触发信号启动HC-RS04测距模块,也就是说,主机要先发送至少10us的高电平,触发HC-RS04,模块内部发出信号是传感器自动回应的,我们不用去管它。输出回响信号是我们需要关注的。信号输出的高电平就是超声波发出到重新返回接收所用的时间。用定时器,可以把这段时间记录下来,算出距离,结果要除于2,因为总时间是发送和接收的时间总和。
部分源程序如下:- #include "cs.h"
- #include "stm32f10x.h"
- #include "delay.h"
- #include "usart.h"
- /*记录定时器溢出次数*/
- uint overcount=0;
- /*设置中断优先级*/
- void NVIC_Config(void)
- {
- NVIC_InitTypeDef NVIC_InitStructer;
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
-
- NVIC_InitStructer.NVIC_IRQChannelPreemptionPriority=0;
- NVIC_InitStructer.NVIC_IRQChannelSubPriority=0;
- NVIC_InitStructer.NVIC_IRQChannel=TIM2_IRQn;
- NVIC_InitStructer.NVIC_IRQChannelCmd=ENABLE;
-
- NVIC_Init(&NVIC_InitStructer);
- }
- /*初始化模块的GPIO以及初始化定时器TIM2*/
- void CH_SR04_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructer;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructer;
-
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
-
- /*TRIG触发信号*/
- GPIO_InitStructer.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_InitStructer.GPIO_Mode=GPIO_Mode_Out_PP;
- GPIO_InitStructer.GPIO_Pin=GPIO_Pin_8;
- GPIO_Init(GPIOB, &GPIO_InitStructer);
-
- /*ECOH回响信号*/
- GPIO_InitStructer.GPIO_Mode=GPIO_Mode_IN_FLOATING;
- GPIO_InitStructer.GPIO_Pin=GPIO_Pin_9;
- GPIO_Init(GPIOB, & GPIO_InitStructer);
-
- /*定时器TIM2初始化*/
- TIM_DeInit(TIM2);
- TIM_TimeBaseInitStructer.TIM_Period=999;//定时周期为1000
- TIM_TimeBaseInitStructer.TIM_Prescaler=71; //分频系数72
- TIM_TimeBaseInitStructer.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
- TIM_TimeBaseInitStructer.TIM_CounterMode=TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructer);
-
- TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//开启更新中断
- NVIC_Config();
- TIM_Cmd(TIM2,DISABLE);//关闭定时器使能
-
- }
- float Senor_Using(void)
- {
- float length=0,sum=0;
- u16 tim;
- uint i=0;
- /*测5次数据计算一次平均值*/
- while(i!=5)
- {
- PBout(8)=1; //拉高信号,作为触发信号
- delay_us(20); //高电平信号超过10us
- PBout(8)=0;
- /*等待回响信号*/
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==RESET);
- TIM_Cmd(TIM2,ENABLE);//回响信号到来,开启定时器计数
-
- i+=1; //每收到一次回响信号+1,收到5次就计算均值
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==SET);//回响信号消失
- TIM_Cmd(TIM2,DISABLE);//关闭定时器
-
- tim=TIM_GetCounter(TIM2);//获取计TIM2数寄存器中的计数值,一边计算回响信号时间
-
- length=(tim+overcount*1000)/58.0;//通过回响信号计算距离
-
- sum=length+sum;
- TIM2->CNT=0; //将TIM2计数寄存器的计数值清零
- overcount=0; //中断溢出次数清零
- delay_ms(100);
- }
- length=sum/5;
- return length;//距离作为函数返回值
- }
- void TIM2_IRQHandler(void) //中断,当回响信号很长是,计数值溢出后重复计数,用中断来保存溢出次数
- {
- if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
- {
- TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志
- overcount++;
-
- }
- }
复制代码
【必读】版权免责声明
1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
|