1.模块简介
GY-53 是一款低成本数字红外测距传感器模块。工作电压 3-5v,功耗小,体积小。
工作原理是,红外 LED 发光,照射到被测物体后,返回光经过 MCU 接收,MCU 计算出时间差得到距离,直接输出距离值。 此模块有两种方式读取数据,即 串口 UART(TTL 电平)+PWM(1 线) 或者芯片 IIC 模式,串口的波特率有 9600bps 与 115200bps,可配置,有连续,询问输出两种方式, 可掉电保存设置。模块另外可以设置单独传感器芯片工作模式, 作为简单传感器模块,MCU 不参与数据处理工作。
2.引脚说明
该模块共有12个引脚,两个VCC,两个GND,TX引脚为串口 USART_TX ,RX引脚为串口 USART_RX ,PWM引脚可以把距离转换为 PWM 形式输出 ,SDA即芯片SDA引脚,SCL即芯片SCL引脚,PS引脚为串口/IIC 模式转换引脚, 当ps=1(默认),串口UART模式,Pin3 为 TX,Pin4 为 RX,TTL 电平,PWM 输出工作;当ps = 0 (接 GND 时) IIC 模式,用户可自行操作芯片,模块自带 MCU 不对芯片操作,PWM 输出不工作。
3.使用介绍
我使用的是PWM模式,所以在这里就只介绍PWM模式的使用方法。
这款测距模块在PWM模式下使用和超声波模块十分类似(没有用过超声波模块也没有关系),编程思路大致如下:
当接收到高电平信号后,打开定时器开始计时,信号结束后关闭定时器,这样就得到了高电平的时间,模块内部芯片会输出周期为20HZ的PWM波,高电平的时间对应测得的距离(这是模块内部芯片决定的,我们不用管),公式如下:
*距离(mm)= 高电平时间(ms)100 = 高电平时间(us)/10
例如:测得高电平时间为10000us,则距离 = 10000/10 = 1000mm
4.代码实现
获取时间用的基本定时器TIM6,通过中断来计时。
然后通过调取这个函数,即可得到距离:
float Hcsr04GetLength(void)
{
uint32_t t = 0;
float lengthTemp = 0;
delay_ms(500);
while (GY53_Receive == 0); //等待接收口高电平输出
OpenTimerForGY(); //打开定时器
while (GY53_Receive == 1); //
CloseTimerForGY(); //关闭定时器
t = GetGYTimer(); //获取时间,分辨率为1US
lengthTemp = (float)t / 10;
return lengthTemp;
}
打开定时器的函数:
static void OpenTimerForGY(void)
{
//设置TIM计数器寄存器的值
TIM_SetCounter(BASIC_TIM,0); //清除计数
time = 0;
TIM_Cmd(BASIC_TIM,ENABLE); //使能TIMX外设
}
关闭定时器的函数:
static void CloseTimerForGY(void)
{
TIM_Cmd(BASIC_TIM,DISABLE); //使能TIMX外设
}
获取时间的函数:
uint32_t GetGYTimer(void)
{
uint32_t t = 0;
t = time * 1000; //将ms转化为us
t = t + TIM_GetCounter(BASIC_TIM); //得到总us
TIM6-> CNT = 0; //将TIM6计数寄存器的计数值清零 (上一个函数返回值)
delay_ms(50);
return t;
}
5.结果
在main函数里调用上述函数,通过串口将得到的数据打印出来。
main函数如下:
int main (void)
{
BASIC_TIM_Init();//基本定时器初始化
USART_Config(); //串口初始化
GY53_Init();
TIM_Init(); //高级定时器初始化
delay_ms(500);
while(1)
{
printf("距离为%3fmm\n",Hcsr04GetLength());
delay_ms(500);
}
}
显示结果如下:
注意:我在使用中发现,此模块在使用时如果倾角变化,对测量值会有较大影响,所以在使用时要尽量使模块垂直与水平面,以便得到较为准确的值。
原代码下载地址:https://download.csdn.net/download/weixin_43737995/11574506