GY39测量温湿度和光照强度用C51单片机实现
一、GY-39的介绍
GY-39 是一款低成本,气压,温湿度,光强度传感器模块。工作电压 3-5v,功耗小,安装方便。其工作原理是, MCU 收集各种传感器数据,统一处理,直接输出计算后的结果。
在此模块中,有两种方式读取数据,即串口 UART( TTL 电平)或者 IIC( 2 线)。这里就是利用C51的串口采集GY-39的数据。
通信协议
串口通信参数可以有以下两种选择:
1、波特率: 9600 bps 校验位: N 数据位: 8 停止位: 1
2、波特率: 115200 bps 校验位: N 数据位: 8 停止位: 1
我们将使用方式一,用9600的波特率 (如果是stm32可以使用方式二)
GY39的命令数据帧格式
GY39模块是以命令的方式发送数据的,简单来说就是当你发送一个指令,GY39就回复对应的数据给你,如:你发送取光照强度的指令,Gy39就回给你光照的数据。
GY-39模块的所有串口指令格式为:
帧头: 0xa5(固定的)
所以指令格式:帧头+指令+校验和(8bit)
发送命令: 0xA5+0x81+0x26,表示连续输出光照强度,掉电后保存该设置,重新上电后将自动连续输出光照强度;
发送命令: 0xA5+0x82+0x27,表示连续输出温度、气压、湿度、海拔,掉电后保存该设置,重新上电后将自动连续输出;
接收的数据帧格式
模块输出格式,每帧包含 8-13 个字节(十六进制)
不是8位就是13位
①.Byte0: 0x5A 帧头标志
②.Byte1: 0x5A 帧头标志
③.Byte2: 0x15 本帧数据类型(参考含义说明)
④.Byte3: 0x04 数据量
⑤.Byte4: 0x000xFF 数据前高 8 位0xFF 数据前低 8 位
⑤.Byte5: 0x00
⑥.Byte6: 0x000xFF 数据后高 8 位0xFF 数据后低 8 位
⑦.Byte7: 0x00
⑧.Byte8: 0x00~0xFF 校验和(前面数据累加和,仅留低 8 位)
其中不管是8为数据还是13位数据:
- 前面两位都是0xA5
- 第三位是数据类型
- 第四位是该数据帧的数据位的长度
- 最后一位是校验和(可以不用管)
其中第三位和第四位最为重要
第三位
当第三位的数据位为 “0X15” 表示这个数据帧为带有光照数据的数据帧
当第三位的数据位为 “0X45” 表示这个数据帧为温度、气压、湿度、海拔数据的数据帧
第四位数据
表示该数据帧的数据位的大小
如:0x04 表示后面4个位都是数据位
光照值的计算
光照强度计算方法(当 Byte2=0x15 时,数据:Byte4~Byte7) :
Lux=(前高 8 位<<24) | (前低 8 位<<16) | (后高 8 位<<8) | 后低 8 位 单位 lux
例:一帧数据
<5A- 5A- 15 -04- 00 -00- FE- 40- 0B >
Lux=(0x00<<24)|(0x00<<16)|(0xFE<<8)|0x40
Lux=Lux/100 =650.88 (lux)
温度、气压、湿度、海拔数据的计算
温度、气压、湿度、海拔,计算方法(当 Byte2=0x45 时):
温度: Byte4Byte5Byte9
T=(高 8 位<<8)|低 8 位
T=T/100 单位℃
气压: Byte6
P=(前高 8 位<<24) | (前低 8 位<<16) | (后高 8 位<<8) | 后低 8 位
P=P/100 单位 pa
湿度: Byte10Byte11Byte134
Hum=(高 8 位<<8)|低 8 位
Hum=Hum/100 百分制
海拔: Byte12
H=(高 8 位<<8)|低 8 位 单位 m
例:一帧数据
< 5A -5A -45 -0A -0B -2D -00 -97 -C4 -3F -12- 77 -00- 9C- FA >
T=(0x0B<<8)|0x2D=2861
温度 T=2861/100=28.61 (℃ )
P=(0x00<<24)|(0x97<<16)|(C4<<8)|3F=9946175
气压 P=9946175/100=99461.75 (pa)
Hum=(0x12<<8)| 77=4727
湿度 Hum=4727/100=47.27 (%)
海拔 H=(0x00<<8)|0x9c=156 (m)
二、利用C51计算光照、温度、湿度值
接线:
TXD -> DR
RXD -> CT
如图:
因为GY-39是要单片机不断发送命令,才会读取数据发送给我们的51单片机所以我们以采取轮询的方式,不断给单片机发送我们的命令数据帧,这样我们就可以实现一直获取数据。
我们的主函数
1 | while(1) |
C51发送命令数据给GY-39
1 | void send_buff(u8 *tem_buff,u8 buff_size) |
串口中断函数
1 | void USART_IRQHandler(void)interrupt 4 |