专栏名称: CW32生态社区
以开放、共享、互助为理念,致力于构建武汉芯源半导体CW32系列MCU生态社区。无论是嵌入式MCU小白还是想要攻破技术难题的工程师,亦或是需求解决方案的产品经理,都可在CW32生态社区汲取营养、共同成长。
目录
相关文章推荐
51好读  ›  专栏  ›  CW32生态社区

【CW32模块使用】SR04超声波测距传感器

CW32生态社区  · 公众号  · 科技创业 科技自媒体  · 2024-09-19 18:51

主要观点总结

本文主要描述了在CW32F030C8T6开发板上移植超声波距离探测模块的过程,包括资料下载、规格参数、移植过程、函数说明和移植验证。

关键观点总结

关键观点1: 模块来源和实物展示

提供了模块来源的链接和提取码,以便获取相关资料。

关键观点2: 规格参数

详细列出了超声波模块的工作电压、工作电流、感应角度、探测距离、探测精度、输出方式、管脚数量等规格参数。

关键观点3: 移植过程

描述了移植超声波模块的步骤,包括查看资料、引脚选择、移植至工程等。

关键观点4: 函数说明

详细介绍了超声波模块相关的函数,包括初始化、打开定时器、获取定时器定时时间、关闭定时器、定时器中断服务函数、获取测量距离等。

关键观点5: 移植验证

在main主函数中验证了超声波模块的移植情况,通过输出实际距离来验证模块是否正常工作。


正文

请到「今天看啥」查看全文


0

01
模块来源

>>>

模块实物展示


资料下载链接:

https://pan.baidu.com/s/1sSah9PvLBrmbA7So-6YcSw

资料提取码:qq35

02
规格参数

>>>

工作电压 :3-5.5V

工作电流 :5.3MA

感应角度 :小于15度

探测距离 :2CM-600CM

探测精度 :0.1CM+1%

输出方式 : GPIO

管脚数量 :4 Pin

以上信息见厂家资料文件

0 3
移植过程

>>>

我们的目标是将例程移植至CW32F030C8T6开发板上【能够判断前方障碍物距离的功能】。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。

3. 1
查看资料

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

当测量距离超过 HC-SR04 的测量范围时,仍会通过 Echo管脚输出高电平的信号,高电平的宽度约为 66ms。如图所示:

测量周期:当接收到 HC-SR04 通过 Echo 管脚输出的高电平脉冲后,便可进行下一次测量,所以测量周期取决于测量距离,当距离被测物体很近时,Echo 返回的脉冲宽度较窄,测量周期 就很短;当距离被测物体比较远时,Echo 返回的脉冲宽度较宽,测量周期也就相应的变长。最坏情况下,被测物体超出超声波模块的测量范围,此时 返回的脉冲宽度最长,约为 66ms,所以最坏情况下的测量周期稍大于 66ms 即可(取 70ms 足够)。

3. 2
引脚选择

接线表


3. 3
移植至工程

工程模板参考入门手册的工程模板

移植步骤中的导入.c和.h文件与 【CW32模块使用】DHT11温湿度传感器 相同, 只是将.c和.h文件更改为bsp_ultrasonic.c与bsp_ultrasonic.h。 这里不再过多讲述,移植完成后面修改相关代码。

在文件bsp_ultrasonic.c中,编写如下代码。

/* * Change Logs: * Date           Author       Notes * 2024-06-20     LCKFB-LP    first version */
#include "bsp_ultrasonic.h"

unsigned char msHcCount = 0;//ms计数float distance = 0;
/****************************************************************** * 函 数 名 称:bsp_ultrasonic * 函 数 说 明:超声波初始化 * 函 数 形 参:无 * 函 数 返 回:无 * 作 者:LC * 备 注:TRIG引脚负责发送超声波脉冲串******************************************************************/void Ultrasonic_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; BTIM_TimeBaseInitTypeDef BTIM_TimeBaseInitStruct; // 定时器基本初始化结构体
RCC_SR04_ENABLE(); // 使能GPIO时钟 RCC_TIMER_ENABLE(); // 使能定时器时钟
// GPIO配置参数 GPIO_InitStructure.Pins = GPIO_TRIG; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出 GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(PORT_SR04, &GPIO_InitStructure);

GPIO_InitStructure.Pins = GPIO_ECHO; GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP; // 上拉输入
GPIO_Init(PORT_SR04, &GPIO_InitStructure);
// 禁止中断,以安全地配置NVIC __disable_irq();
// 开启BTIM1中断,并关联到NVIC NVIC_EnableIRQ(TIMER_IRQ);
// 允许中断,恢复中断状态 __enable_irq();
// 配置定时器模式、周期和预分频器 BTIM_TimeBaseInitStruct.BTIM_Mode = BTIM_Mode_TIMER; // 设置为定时器模式 BTIM_TimeBaseInitStruct.BTIM_Period = 1000 - 1; // 设置周期,使得定时器每1ms产生一次溢出中断 BTIM_TimeBaseInitStruct.BTIM_Prescaler = BTIM_PRS_DIV64; // 预分频器设置为64,以降低时钟频率
// 使用上述配置初始化定时器BTIM1 BTIM_TimeBaseInit(PORT_TIMER, &BTIM_TimeBaseInitStruct);
// 使能BTIM1的溢出中断 BTIM_ITConfig(PORT_TIMER, BTIM_IT_OV, ENABLE);
// // 启动定时器BTIM1// BTIM_Cmd(PORT_TIMER, ENABLE);

}/****************************************************************** * 函 数 名 称:Open_Timer * 函 数 说 明:打开定时器 * 函 数 形 参:无 * 函 数 返 回:无 * 作 者:LC * 备 注:******************************************************************/void Open_Timer(void){ BTIM_SetCounter(PORT_TIMER, 0); // 清除定时器计数
msHcCount = 0;
BTIM_Cmd(PORT_TIMER, ENABLE); // 使能定时器}
/****************************************************************** * 函 数 名 称:Get_TIMER_Count * 函 数 说 明:获取定时器定时时间 * 函 数 形 参:无 * 函 数 返 回:数据 * 作 者:LC * 备 注:******************************************************************/uint32_t Get_TIMER_Count(void){ uint32_t time = 0; time = msHcCount*1000; // 得到us time += BTIM_GetCounter(PORT_TIMER); // 得到ms
BTIM_SetCounter(PORT_TIMER, 0); // 清除定时器计数 delay_ms(10); return time ;}
/****************************************************************** * 函 数 名 称:Close_Timer * 函 数 说 明:关闭定时器 * 函 数 形 参:无 * 函 数 返 回:无 * 作 者:LC * 备 注:******************************************************************/void Close_Timer(void){ BTIM_Cmd(PORT_TIMER, DISABLE); // 关闭定时器}
/****************************************************************** * 函 数 名 称:TIMER_IRQHandler * 函 数 说 明:定时器中断服务函数 * 函 数 形 参:无 * 函 数 返 回:无 * 作 者:LC * 备 注:1ms进入一次******************************************************************/void TIMER_IRQHandler(void){ if (BTIM_GetITStatus(CW_BTIM1, BTIM_IT_OV)) // 检查定时器中断发生 { msHcCount++;
BTIM_ClearITPendingBit(PORT_TIMER, BTIM_IT_OV); // 清除中断标志 }}

/****************************************************************** * 函 数 名 称:Hcsr04GetLength * 函 数 说 明:获取测量距离 * 函 数 形 参:无 * 函 数 返 回:测量距离 * 作 者:LC * 备 注:无******************************************************************/float Hcsr04GetLength(void){ /*测5次数据计算一次平均值*/ float length = 0; float t = 0; float sum = 0; unsigned int i = 0; while(i != 10) {
SR04_TRIG(1);//trig拉高信号,发出高电平 delay_1us(20);//持续时间超过10us SR04_TRIG(0);//trig拉低信号,发出低电平 /*Echo发出信号 等待回响信号*/ /*输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1; (此时应该启动定时器计时);当超声波返回被模块接收到时,回波引 脚端的电平会由1变为0; (此时应该停止定时器计数),定时器记下的这个时间即为 超声波由发射到返回的总时长;*/
while(SR04_ECHO() == GPIO_Pin_RESET);//echo等待回响
Open_Timer(); //打开定时器
i++;
while(SR04_ECHO() == GPIO_Pin_SET);
Close_Timer(); // 关闭定时器
t = Get_TIMER_Count(); // 获取时间,分辨率为1us length = (float)t / 58.0f; // cm sum += length; }
length = sum/10;//五次平均值 distance = length; return length;}


在文件bsp_ultrasonic.h中,编写如下代码。

/* * Change Logs: * Date           Author       Notes * 2024-06-20     LCKFB-LP    first version */#ifndef _BSP_ULTRASONIC_H_#define _BSP_ULTRASONIC_H_
#include "board.h"
#define RCC_SR04_ENABLE() __RCC_GPIOA_CLK_ENABLE()
#define PORT_SR04 CW_GPIOA
#define GPIO_TRIG GPIO_PIN_1#define GPIO_ECHO GPIO_PIN_2
#define RCC_TIMER_ENABLE() __RCC_BTIM_CLK_ENABLE()#define PORT_TIMER CW_BTIM1
#define TIMER_IRQ BTIM1_IRQn#define TIMER_IRQHandler BTIM1_IRQHandler
#define SR04_TRIG(x) GPIO_WritePin( PORT_SR04, GPIO_TRIG, x?GPIO_Pin_SET:GPIO_Pin_RESET)#define SR04_ECHO() GPIO_ReadPin( PORT_SR04, GPIO_ECHO )
void Ultrasonic_Init(void);//超声波初始化float Hcsr04GetLength(void );//获取超声波测距的距离
#endif


0 4
移植验证

>>>

在自己工程中的main主函数中,编写如下。

/* * Change Logs: * Date           Author       Notes * 2024-06-20     LCKFB-LP    first version */#include "board.h"#include "stdio.h"#include "bsp_uart.h"#include "bsp_ultrasonic.h"
int32_t main(void){ board_init(); // 开发板初始化
uart1_init(115200); // 串口1波特率115200
Ultrasonic_Init(); printf("Start.......\r\n");
while(1) { printf((const char *)"距离为 = %.2fCM\r\n",Hcsr04GetLength() ); delay_ms(500); }}

移植现象:距离20CM处摆放障碍物,输出换算后的实际距离。

模块移植成功案例代码:

链接: https://pan.baidu.com/s/1AwXOFbLryUoYPW-ueRZ_qA?pwd=LCKF

提取码:LCKF


END

往期回顾

REVIEW

【产品应用】CW32电动工具产品开源

【产品应用】基于CW32的智能充电宝(方案开源)

【产品应用】CW-W88水泵通用控制板设计方案(已开源)

【产品应用】基于CW32的角磨机控制器产品方案

【产品方案】基于CW32F030C8的低压无刷风机无感控制器

【产品方案】基于CW32的无刷直流空心杯电机有感控制驱动方案

【产品方案】基于CW32的无刷直流空心杯电机无感方波控制驱动方案

从0到1,开启产品级智能硬件设计之路!

CW32生态社区(WX)群




扫码加入QQ群

3群| 610403240

获取资料及 “开发者扶持计划” 第一手资讯









请到「今天看啥」查看全文