0
hc-sr04
前言:因最近要用到测距功能,先用赤菟测试一下,看看效果。
一、公司就有的一个小模组HC-SR04,简单介绍一下这个模组。
1、概述
HC-SR04 超声波测距模块可实现 2cm~5.6m 的非接触测距功能,工作电压为 3V-5.5V,工作电流为 5.3mA,支持 GPIO 通信模式,工作稳定可靠。
2、主要技术参数
电气参数 | HC-SR04超声波测距模块 | 工作电压 | DC 3V-5.5V | 工作电流 | 5.3mA | 工作温度 | -40°C-85°C | 输出方式 | GPIO | 感应角度 | 小于15度 | 探测距离 | 2cm-5.6m | 探测精度 | 0.3cm±1% |
3、模块实物尺寸
如图1所示从左到右依次编号 1,2,3,4。它们的定义如下:
⚫ 1 号 Pin:接 VCC 电源(直流 3V-5.5V)。
⚫ 2 号 Pin:接外部电路的 Trig 端,向此管脚输入一个
10uS 以上的高电平(建议 50us~100us),可触发模块
测距。
⚫ 3 号 Pin:接外部电路的 Echo 端,当测距结束时,此管
脚会输出一个高电平,电平宽度为超声波往返时间之
和。
⚫ 4 号 Pin:接外部电路的地。
4、测距工作原理
如图所示,具体可下载附件pdf查看。
二、赤菟CH32V307主要代码
代码是我从别人程序上借鉴的,移植到307上的。
1、main函数如下
- int main(void)
- {
- float distance = 0;
- Delay_Init();
- USART_Printf_Init(115200);
- Input_Capture_Init(1000-1,72-1);
- printf("SystemClk:%d
- ",SystemCoreClock);
- printf("This is Ultrasonic ranging example
- ");
- while(1)
- {
- distance = Ultrasoniclength(); //cm
- printf("DISTANCE:%3.2f cm
- ",distance);
- Delay_Ms(1000);
- }
- }
复制代码 2、定时器tiM2设置,初始化Trig和Echo两个引脚。
- void Input_Capture_Init( u16 arr, u16 psc )
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- //使能IM2时钟
- RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE);
- ultrasonic_GPIO_Init(); //配置Trig和Echo两个引脚
- TIM_DeInit(TIM2);
- //定时器周期,实际就是设定自动重载寄存器 ARR 的值, ARR 为要装载到实际自动重载寄存器(即影子寄存器) 的值, 可设置范围为 0 至 65535。
- TIM_TimeBaseInitStructure.TIM_Period = arr;
- //定时器预分频器设置,时钟源经该预分频器才是定时器计数时钟CK_CNT,它设定 PSC 寄存器的值。
- //计算公式为: 计数器时钟频率 (fCK_CNT) 等于fCK_PSC / (PSC[15:0] + 1),可实现 1 至 65536 分频。
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
- //时钟分频,设置定时器时钟 CK_INT 频率与死区发生器以及数字滤波器采样时钟频率分频比。可以选择 1、 2、 4 分频。
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //设置计数模式,向上计数模式
- //TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00; //设置重复计数器的值,0。重复计数器,只有 8 位,只存在于高级定时器。
- TIM_TimeBaseInit( TIM2, &TIM_TimeBaseInitStructure); //初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM1捕获比较中断
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//设置抢占优先级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //设置响应优先级
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能通道
- NVIC_Init(&NVIC_InitStructure);
- TIM_ClearFlag(TIM2, TIM_FLAG_Update);
- TIM_ITConfig( TIM2, TIM_IT_Update, ENABLE ); //使能TIM2更新中断
- TIM_Cmd( TIM2, DISABLE ); //定时器使能
- }
复制代码 3、测量函数
- //一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号
- //为了消除余震的影响,取五次数据的平均值进行加权滤波。
- float Ultrasoniclength(void )
- {
- u32 t = 0;
- int i = 0;
- float length = 0 , sum = 0;
- while(i!=5)
- {
- Start_Trig();
- while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==RESET); //此处一直等,等到为1,进行下一步
- ENABLE_TIM();//回响信号到来,开启定时器计数
- i = i + 1;
- while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==SET); //此处一直等,等到为0,进行下一步,这两段while之间的时间就是高电平时间,即发出到返回接收的时间
- DISABLE_TIM();//回响信号到来,开启定时器计数
- t = TIM_GetCounter(TIM2);
- length=(t+count*1000)/58.0;//通过回响信号计算距离
- sum = length + sum ;
- printf("sum is %3.2f,length is %3.2f,t is %d,count is %d
- ",sum,length,t,count);
- TIM_SetCounter(TIM2,0);
- count = 0;
- Delay_Ms(100);
- }
- length = sum/5.0;
- return length;
- }
复制代码
三、遇到的问题
1、串口打印float类型数据为空,找了半天时间,也咨询了群。最终搞定。
2、解决方法,在MSR里面点击如下图所示打开配置界面。
3、配置界面如下所示,开始选中了论坛中所说2个打印选项,结果还是不行,后面只选择了一个,结果OK了。
四、总结
因超声波测距对测距的物体表面面积有要求大于0.5平方,好像是这个数值。原理就是远了声波过去它有个角度,所以在测试过程中需要注意一下。
以上均属个人理解,如有不对,感谢指正。
超声波测距.zip
(649.28 KB, 下载次数: 25)
|
评分
-
查看全部评分
|