SHT11数字温湿度传感器
2020-09-04 来源:51hei
单片机源程序如下:
#include #include #include 'LCD1602.h' /******************************************************** 宏定义 ********************************************************/ #define uint unsigned int #define uchar unsigned char #define noACK 0 #define ACK 1 #define STATUS_REG_W 0x06 #define STATUS_REG_R 0x07 #define MEASURE_TEMP 0x03 #define MEASURE_HUMI 0x05 #define RESET 0x1e enum { TEMP, HUMI }; typedef union //定义共用同类型 { unsigned int i; float f; } value; /******************************************************** 位定义 ********************************************************/ sbit SCK = P1 ^ 0; sbit DATA = P1 ^ 1; /******************************************************** 变量定义 ********************************************************/ uchar wendu[6]; uchar shidu[6]; /******************************************************** 50us延时函数 ********************************************************/ void delay_50us(uint t) { uint j; for (; t>0; t--) for (j = 19; j>0; j--); } /******************************************************* 液晶显示函数 ********************************************************/ void displaywendu(void) { uchar i; write_com(0x80+0x40); write_data('T'); write_data(':'); for (i = 0; i<3; i++) { write_data(wendu[i]); delay_50us(1); } for (i = 0; i<1; i++) { write_data('.'); delay_50us(1); } for (i = 4; i<5; i++) { write_data(wendu[i]); delay_50us(1); } write_data(0xDF); write_data('C'); } /******************************************************** 液晶显示函数 ********************************************************/ void displayshidu(void) { uchar i; write_com(0x80); write_data('H'); write_data(':'); for (i = 0; i<3; i++) { write_data(shidu[i]); delay_50us(1); } for (i = 0; i<1; i++) { write_data('.'); delay_50us(1); } for (i = 4; i<5; i++) { write_data(shidu[i]); delay_50us(1); } write_data('%'); write_data('R'); write_data('H'); } /******************************************************** SHT11写字节程序 ********************************************************/ char s_write_byte(unsigned char value) { unsigned char i, error = 0; for (i = 0x80; i>0; i >>= 1) //高位为1,循环右移 { if (i&value) DATA = 1; //和要发送的数相与,结果为发送的位 else DATA = 0; SCK = 1; _nop_(); _nop_(); _nop_(); //延时3us SCK = 0; } DATA = 1; //释放数据线 SCK = 1; error = DATA; //检查应答信号,确认通讯正常 _nop_(); _nop_(); _nop_(); SCK = 0; DATA = 1; return error; //error=1 通讯错误 } /******************************************************** SHT11读字节程序 ********************************************************/ char s_read_byte(unsigned char ack) { unsigned char i, val = 0; DATA = 1; //释放数据线 for (i = 0x80; i>0; i >>= 1) //高位为1,循环右移 { SCK = 1; if (DATA) val = (val | i); //读一位数据线的值 SCK = 0; } DATA = !ack; //如果是校验,读取完后结束通讯; SCK = 1; _nop_(); _nop_(); _nop_(); //延时3us SCK = 0; _nop_(); _nop_(); _nop_(); DATA = 1; //释放数据线 return val; } /******************************************************** SHT11启动传输 ********************************************************/ void s_transstart(void) { DATA = 1; SCK = 0; //准备 _nop_(); SCK = 1; _nop_(); DATA = 0; _nop_(); SCK = 0; _nop_(); _nop_(); _nop_(); SCK = 1; _nop_(); DATA = 1; _nop_(); SCK = 0; } /******************************************************** SHT11连接复位 ********************************************************/ void s_connectionreset(void) { unsigned char i; DATA = 1; SCK = 0; //准备 for (i = 0; i<9; i++) //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位 { SCK = 1; SCK = 0; } s_transstart(); //启动传输 } /******************************************************** SHT11温湿度检测 ********************************************************/ char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode) { unsigned error = 0; unsigned int i; s_transstart(); //启动传输 switch (mode) //选择发送命令 { case TEMP: error += s_write_byte(MEASURE_TEMP); break; //测量温度 case HUMI: error += s_write_byte(MEASURE_HUMI); break; //测量湿度 default: break; } for (i = 0; i<65535; i++) if (DATA == 0) break; //等待测量结束 if (DATA) error += 1; // 如果长时间数据线没有拉低,说明测量错误 *(p_value) = s_read_byte(ACK); //读第一个字节,高字节 (MSB) *(p_value + 1) = s_read_byte(ACK); //读第二个字节,低字节 (LSB) *p_checksum = s_read_byte(noACK); //read CRC校验码 return error; // error=1 通讯错误 } /******************************************************** SHT11温湿度值标度变换及温度补偿 ********************************************************/ void calc_sth10(float *p_humidity, float *p_temperature) { const float C1 = -4.0; // 12位湿度精度 修正公式 const float C2 = +0.0405; // 12位湿度精度 修正公式 const float C3 = -0.0000028; // 12位湿度精度 修正公式 const float T1 = +0.01; // 14位温度精度 5V条件 修正公式 const float T2 = +0.00008; // 14位温度精度 5V条件 修正公式 float rh = *p_humidity; // rh: 12位 湿度 float t = *p_temperature; // t: 14位 温度 float rh_lin; // rh_lin: 湿度 linear值 float rh_true; // rh_true: 湿度 ture值 float t_C; // t_C : 温度 ℃ t_C = t*0.01 - 40; //补偿温度 rh_lin = C3*rh*rh + C2*rh + C1; //相对湿度非线性补偿 rh_true = (t_C - 25)*(T1 + T2*rh) + rh_lin; //相对湿度对于温度依赖性补偿 if (rh_true>100)rh_true = 100; //湿度最大修正 if (rh_true<0.1)rh_true = 0.1; //湿度最小修正 *p_temperature = t_C; //返回温度结果 *p_humidity = rh_true; //返回湿度结果 } /******************************************************** 主函数 ********************************************************/ void main(void) { unsigned int temp, humi; value humi_val, temp_val; //定义两个共同体,一个用于湿度,一个用于温度 unsigned char error; //用于检验是否出现错误 unsigned char checksum; //CRC LcdInitiate(); ……………………
下一篇:基于51单片机的温度报警器