一、GY56简介
1. 概述
GY-56 是一款低成本数字红外测距传感器模块。 工作电压 3-5v,功耗小,体积小,安装方便。 其工作原理是,红外 LED 发光,照射到被测物体后,返回光经过 MCU 接收,MCU 计算出时间差,得到距离。直接输出距离值。此模块,有两种方式读取数据,即串口 UART(TTL 电平)+IIC(2 线)模式,串口的波特率有 9600bps 与 115200bps,可配置,有连续,询问输出两种方式,可掉电保存设置。GY-56 可以设置上下限距离报警值,开关量输出,在设定的区间内有被测物体挡住,直接输出高电平。IIC 模式下,如果需要,可以设置内部 IIC 地址不同,以便多个传感器直接接在同一个总线。
2. 特点
- 高性价比
- 内置 MCU 计算距离
- IIC、串口通信协议
- 配有相应的上位机软件
3. 参数
4. 引脚说明
5. 应用
- 智能机器人
- 教学实验室仪器
- 生产线产品检测
- 红外测距
二、通信协议
1. 串口
Tips: 模块默认为串口
(1)串口通信参数(默认波特率值 9600bps,可通过软件设定)
波特率:9600 bps 校验位:N 数据位:8 停止位:1
波特率:115200 bps 校验位:N 数据位:8 停止位:1
(2)、模块输出格式,每帧包含 8-13 个字节(十六进制):
①.Byte0: 0x5A 帧头标志
②.Byte1: 0x5A 帧头标志
③.Byte2: 0x15 本帧数据类型
④.Byte3: 0x03 数据量
⑤.Byte4: 0x00~0xFF 数据前高 8 位
⑥.Byte5: 0x00~0xFF 数据前低 8 位
⑦.Byte6: 0x00~0xFF 模块测量模式
⑧.Byte7: 0x00~0xFF 模块温度
⑨.Byte8: 0x00~0xFF 校验和(前面数据累加和,仅留低 8 位)
数据计算方法(距离长度计算方法):
Distance= (Byte4<<8) | Byte5 单位 cm
Mode= Byte6
Temp= Byte7(MCU 温度)
例:一帧数据
< 5A-5A-15-04-00-0A-02-1A-F3>
Distance =(0x00<<8)|0x0A =10cm
Mode=2 (高精度模式)
Temp=0x1A=26℃
(3)命令字节,由外部控制器发送至 GY-56 模块(十六进制)
串口命令指令:
命令格式:0xA5+功能指令+指令值+sum
例 1:设置串口连续输出数据,(如需掉电保存,请发送掉电保存指令)
连续输出指令=0xA5+0x65+0x01+0x0B
例 2:设置在 10cm-50cm 的区间范围内 OUT 引脚输出高电平
(如需掉电保存,请发送掉电保存指令)
设置上限阀值 50CM=0xA5+0x98+0x32+0x6F
设置下限阀值 10CM=0xA5+0xA9+0x0A+0x58
例 3: 掉电保存指令 = 0xA5+0x87+0x01+0x2D
2. IIC协议
当 GY-56 模块硬件 ps 焊点焊上时候使用,CT 为 SCL,DR 为 SDA
IIC 时钟:250K 以下,模块默认 8bit IIC 地址为 0XE0;
1bit write:0;
1bit read: 1;
三、模块使用方法
该模块为串口和 IIC 输出模块,模块默认为串口模式。模块接入电源后,检测距离不在上限阀值内,LED 会闪亮 1 秒,检测距离在上限阀值内,LED 指示灯会长亮,如果指示
灯一直闪烁,说明模块初始化失败,模块不能使用。
串口模式(默认):PS 端口拉高(默认,PS 焊点开放),模块上电,默认配置为波特率9600、高精度测量、连续输出模式;使用该模块配套的上位机可方便的对模块进行相应的设置;上位机使用前请先选择好端口和波特率,然后再点击“打开串口”按钮,此时,上位机将显示对应的数据。
串口输出模式分两种,一种连续输出,一种查询输出。连续输出的频率根据测量模式
的不同而不同,具体参见 Byte6 代表的含义说明;查询输出的形式为模块接收到查询指令后,模块开启一次测量,测量完毕后再返回一帧测量数据。不同的输出模式和不同测量模式,导致模块的消耗电流也不同,模块在不测量距离时,电流约为 15mA,查询输出模式在测量结束后电流约为 15mA,连续输出模式电流具体参见 Byte6 代表的含义说明。
- 1. SET、OUT 引脚使用说明:
S 表示模块与被测物体之间的距离;
S1 表示设定的最大警界阀值(上限阀值);
S2 表示设定的最小警界阀值(下限阀值);
S3 表示解除最大警界状态值;S3 和 S1 的关系,S3+3≤S1。例如 S1=100,则 S3≤97;
S4 表示解除最小警界状态值;S4 和 S2 的关系,S4-3≥S2。例如 S2=50,则 S3≥53;
OUT 引脚的状态为高电平和低电平两种。高电平表示 S2<S<S1;低电平表示 S>S1 或 S<S2。
(1)OUT 由高电平变低电平。当模块 S>S1 或 S<S2 时,OUT 引脚变成低电平,模块 LED灯将由亮变灭。
(2)OUT 由低电平变高电平。当 S>S1,让 S≤S3 时(即当实际距离低于最大警界阀值 3cm时),OUT 引脚由低电平变高电平,模块 LED 灯将由灭变亮。当 S<S2,让 S≥S4 时(即当实际距离大于最小警界阀值 3cm 时),OUT 引脚由低电平变高电平,模块 LED 灯将由灭变亮。
- 2. 设置最大警界阀值:可通过发送指令外,也可通过 SET 引脚手动来设置。
(1)模块连续输出模式下,例如设置最大警界阀值 S1 为 100cm,则将模块放置在据被测物体 97cm 的位置进行 SET 引脚设置,或者发送指令:(A5 98 64 A1)0x64 是十进制的 100。
(2)手动 SET 引脚接入 3.3V 高电平,大约 3 秒,待模块 LED 指示灯闪速 2 下,此时断开 SET 引脚 3.3V 连接,断开后大约 5 秒,待 LED 闪烁 3 下,则设置成功。如果 LED 闪烁 4下,表示设置失败。失败原因有两种,一种是,接入高电平时间不够,另一种是设置的距离值小于最小警界阀值。
- 3. 设置最小警界阀值:可通过发送指令外,也可通过 SET 引脚来设置。
(1)模块连续输出模式下,例如设置最小警界阀值 S2 为 50cm,则将模块放置在据被测物体 53cm 的位置,进行 SET 引脚设置, 或者发送指令:(A5 A9 32 B2)0x32 是十进制的 50。
(2)手动 SET 引脚接入 GND,大约 3 秒,待模块 LED 指示灯闪速 2 下,此时断开 SET 引脚 GND 连接,断开后大约 5 秒,待 LED 闪烁 3 下,则设置成功。如果 LED 闪烁 4 下,表示设置失败。失败原因有两种,一种是,接入低电平时间不够,另一种是设置的距离值大于最大警界阀值。
- 4. 串口下 GY56 模块校准说明:
该模块由测距传感器和一个 MCU 组成。
(1)SPADs 修正: 当测距传感器上方被透明材质物体覆盖,模块需进行一次该修正,
并上电后加载 SPADs 修正参数。默认情况下,模块在每次上电后会进行一次 SPADs 修正操作,如用户手动执行一次 SPADs 修正后,设置了上电加载 SPADs 修正参数则模块不进行上电后 SPADs 修正操作,这样可以缩短模块初始化时间;通过上位机发送十六进制 A5 0A 01 B0 给模块,模块 LED 亮起,待熄灭校准完成。
(2)温度修正: 当模块工作环境温度变化超过 8 摄氏度,测距传感器灵敏度会发生改变,需进行一次温度修正;默认情况下,模块在每次上电后会进行一次温度修正操作,如模块工作环境温度恒定,可进手动进行一次温度修正后,设置模块上电后加载温度修正参数,这样可以缩短模块初始化时间;如用户开启了自动温度修正,则模块根据 MCU 温度超过 8度后,自行进行一次温度修正;通过上位机发送十六进制 A5 10 01 B6 给模块,模块 LED亮起,待熄灭校准完成。
(3)偏差校准: 当模块测距值与实际值之间存在一个固有的偏差时,可执行此操作。
偏差校准的指令=0xA5+0x21+指令值+sum,指令值为实际距离值。例如:模块测距值为
13CM,而实际值为 10CM,则指令中的指令值为十进制的 10;如需重新上电后加载该补偿值,需设置上电后加载偏差校准参数。通过上位机发送十六进制指令给模块,模块 LED 亮起,待熄灭校准完成。
(4)窗口校准: 当测距传感器上方被透明材质物体覆盖,模块在全量程测距的值不是线性的情况下,执行该操作。如下图所示:
X 轴为实际值,Y 轴为测量值。绿色虚线说明该材质对测距无影响或是传感器表面
无任务材质覆盖,蓝色线表明为轻度影响,红线为中度影响,绿色实线为重度影响。
窗口校准的指令=0xA5+0x32+指令值+sum;
指令值的选取:使用 17%灰色的反射率目标,则设模块与被测目标的距离为 S。对于
轻度影响的情况下,参见下图左侧蓝线,只要 S 在 AB 之间即可。指令值为实际距离值。中度影响的选取右测红线 AB 之间区域。如需重新上电后加载该补偿值,需设置上电后加载窗口校准参数。通过上位机发送十六进制指令给模块,模块 LED 亮起,待熄灭校准完成。
IIC 模式:该模式为每发送一次启动测量命令,模块才会进行一次测距操作,等待测距完成才能读取距离值,测距时间根据模块所处何种测量模式,如下表,例如是高精度模式,则需在大约 200ms 后读取测距值。模块的测量模式配置需通过串口方式进行设置。
四、GY56 上位机
五、STM32驱动代码
1. 串口初始化
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //使能USART2,GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//USART2_TX GPIOA
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2
//USART2_RX GPIOA
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART2, &USART_InitStructure); //初始化串口2
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART2, ENABLE); //使能串口2
2. 发送指令
void USART_Send(uint8_t *Buffer, uint8_t Length)
{
uint8_t i=0;
while(i<Length)
{
if(i<(Length-1))
Buffer[Length-1]+=Buffer[i];//累加Length-1前的数据
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART2,Buffer[i++]);
}
}
void send_com(u8 function,u8 value )
{
u8 bytes[4]={0};
bytes[0]=0xa5;
bytes[1]=function;//功能指令
bytes[2]=value;//指令值
USART_Send(bytes,4);//发送帧头、功能字节、校验和
}
3. 接收中断
void USART2_IRQHandler(void) //串口2中断服务程序
{
static uint8_t i=0,rebuf[20]={0};
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//判断接收标志
{
rebuf[i++]=USART_ReceiveData(USART2);//读取串口数据,同时清接收标志
if (rebuf[0]!=0x5a)//帧头不对
i=0;
if ((i==2)&&(rebuf[1]!=0x5a))//帧头不对
i=0;
if(i>3)//i等于4时,已经接收到数据量字节rebuf[3]
{
if(i!=(rebuf[3]+5))//判断是否接收一帧数据完毕
return;
switch(rebuf[2])//接收完毕后处理
{
case 0x15:
if(!Receive_ok)//当数据处理完成后才接收新的数据
{
memcpy(re_Buf_Data,rebuf,9);//拷贝接收到的数据
Receive_ok=1;//接收完成标志
}
break;
}
i=0;//缓存清0
}
}
}
4. 数据解析
if(Receive_ok)//串口接收完毕
{
for(sum=0,i=0;i<(re_Buf_Data[3]+4);i++)
sum+=re_Buf_Data[i];
if(sum==re_Buf_Data[i])//校验和判断
{
GY56.distance=re_Buf_Data[4]<<8|re_Buf_Data[5];
GY56.mode=re_Buf_Data[6];
GY56.temp=re_Buf_Data[7];
printf("%d\r\n",GY56.distance);
}
Receive_ok=0;//处理数据完毕标志
}
六、MSP432驱动代码
1. 串口初始化
void UARTA2_Init(void)
{
//1.配置GPIO复用
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
//2.配置UART结构体
#ifdef EUSCI_A_UART_7_BIT_LEN
//固件库v3_40_01_02
//默认SMCLK 48MHz 比特率 115200
const eUSCI_UART_ConfigV1 uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
26, // BRDIV = 26
0, // UCxBRF = 0
111, // UCxBRS = 111
EUSCI_A_UART_NO_PARITY, // No Parity
EUSCI_A_UART_LSB_FIRST, // MSB First
EUSCI_A_UART_ONE_STOP_BIT, // One stop bit
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
EUSCI_A_UART_8_BIT_LEN // 8 bit data length
};
eusci_calcBaudDividers((eUSCI_UART_ConfigV1 *)&uartConfig, 115200); //配置波特率
#else
//固件库v3_21_00_05
//默认SMCLK 48MHz 比特率 115200
const eUSCI_UART_Config uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
26, // BRDIV = 26
0, // UCxBRF = 0
111, // UCxBRS = 111
EUSCI_A_UART_NO_PARITY, // No Parity
EUSCI_A_UART_LSB_FIRST, // MSB First
EUSCI_A_UART_ONE_STOP_BIT, // One stop bit
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
};
eusci_calcBaudDividers((eUSCI_UART_Config *)&uartConfig, 115200); //配置波特率
#endif
//3.初始化串口
UART_initModule(EUSCI_A2_BASE, &uartConfig);
//4.开启串口模块
UART_enableModule(EUSCI_A2_BASE);
//5.开启串口相关中断
UART_enableInterrupt(EUSCI_A2_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
//6.开启串口端口中断
Interrupt_enableInterrupt(INT_EUSCIA2);
//7.开启总中断
Interrupt_enableMaster();
}
2. 发送指令
void USART2_Send(uint8_t *Buffer, uint8_t Length)
{
uint8_t i=0;
while(i<Length)
{
if(i<(Length-1))
Buffer[Length-1]+=Buffer[i];//累加Length-1前的数据
//while (!(UART_getInterruptStatus(EUSCI_A2_BASE, EUSCI_A_UART_TRANSMIT_COMPLETE))); //循环发送,直到发送完毕
UART_transmitData(EUSCI_A2_BASE, Buffer[i++]);
}
}
void send_com(u8 function,u8 value )
{
u8 bytes[4]={0};
bytes[0]=0xa5;
bytes[1]=function;//功能指令
bytes[2]=value;//指令值
USART2_Send(bytes,4);//发送帧头、功能字节、校验和
}
3. 接收中断文章来源:https://www.toymoban.com/news/detail-836002.html
void EUSCIA2_IRQHandler(void)
{
uint32_t status = UART_getEnabledInterruptStatus(EUSCI_A2_BASE);
static uint8_t i=0,rebuf[20]={0};
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG) //接收中断
{
rebuf[i++]=MAP_UART_receiveData(EUSCI_A2_BASE);;//读取串口数据,同时清接收标志
if (rebuf[0]!=0x5a)//帧头不对
i=0;
if ((i==2)&&(rebuf[1]!=0x5a))//帧头不对
i=0;
if(i>3)//i等于4时,已经接收到数据量字节rebuf[3]
{
if(i!=(rebuf[3]+5))//判断是否接收一帧数据完毕
return;
switch(rebuf[2])//接收完毕后处理
{
case 0x15:
if(!Receive_ok)//当数据处理完成后才接收新的数据
{
memcpy(re_Buf_Data,rebuf,9);//拷贝接收到的数据
Receive_ok=1;//接收完成标志
}
break;
}
i=0;//缓存清0
}
}
}
4. 数据解析文章来源地址https://www.toymoban.com/news/detail-836002.html
if(Receive_ok)//串口接收完毕
{
for(sum=0,i=0;i<(re_Buf_Data[3]+4);i++)
sum+=re_Buf_Data[i];
if(sum==re_Buf_Data[i])//校验和判断
{
GY56.distance=re_Buf_Data[4]<<8|re_Buf_Data[5];
GY56.mode=re_Buf_Data[6];
GY56.temp=re_Buf_Data[7];
printf("%d\r\n",GY56.distance);
}
Receive_ok=0;//处理数据完毕标志
}
到了这里,关于GY56 红外激光测距传感器 (内附STM32、MSP432代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!