#ifndef _SHT11_H_ #define _SHT11_H_ #define SHT_TEMP_CMD 0x03 #define SHT_HUMI_CMD 0x05 #define SHT_WR_STAT_CMD 0x06 #define SHT_RD_STAT_CMD 0x07 #define SHT_RST_CMD 0x1E #define SHT_TIMOUT_CNT 60000 #define SHT_ACK 0 #define SHT_NACK 1 typedef enum { SHT_RES_T14_H12, SHT_RES_T12_H8 } sht_res_t; #if V_CPUx10 == 50 #define SHT_100xD1 4000 #endif #if V_CPUx10 == 45 #define SHT_100xD1 3975 #endif #if V_CPUx10 == 35 #define SHT_100xD1 3966 #endif #if V_CPUx10 == 33 #define SHT_100xD1 3964 #endif #if V_CPUx10 == 30 #define SHT_100xD1 3960 #endif uint8_t sht_dat_buf; uint8_t sht_dat[3]; sht_res_t sht_res = SHT_RES_T14_H12; uint8_t inq_temp_flag = 0; uint8_t inq_humi_flag = 0; uint8_t inq_all_flag = 0; typedef enum { SHT_INQ_NONE, SHT_INQ_TEMP, SHT_INQ_HUMI } sht_inq_t; sht_inq_t sht_inq = SHT_INQ_NONE; typedef enum { SHT_RESP_OK, SHT_RESP_NOT_FOUND, SHT_RESP_TIMEOUT, } sht_response_t; sht_response_t sht_response = SHT_RESP_OK; uint8_t volatile sht_waiting = 0; uint8_t time_500ms_buf1 = 0; uint8_t time_500ms_buf2 = 0; #define THSensGetWaiting() (sht_waiting) #define THSensGetResp() (sht_response) void THSensTempConv() { uint16_t tempx100; tempx100 = sht_dat[0]; tempx100 = tempx100 << 8; tempx100 = tempx100 | sht_dat[1]; //SOt * d2 if (sht_res == SHT_RES_T14_H12) tempx100 = tempx100*1; else tempx100 = tempx100*4; //SOt * d2 + d1 tempx100 -= SHT_100xD1; sht_dat[0] = tempx100 / 100; sht_dat[1] = tempx100 % 100; } void THSensSetRes(sht_res_t res) { sht_res = res; } void THSensDelay() //For 3.3V app, maximum clock is 1MHz. For 5V app, it's 10MHz { #if F_CPU_MHZ > 10 asm volatile("nop\n\t"::); asm volatile("nop\n\t"::); asm volatile("nop\n\t"::); #endif asm volatile("nop\n\t"::); asm volatile("nop\n\t"::); asm volatile("nop\n\t"::); asm volatile("nop\n\t"::); } #define SHT_RD Rdb(SHT_DAT_PINP,SHT_DAT_PIN) #define SHT_RELES Setb(SHT_DAT_PORT,SHT_DAT_PIN); Clrb(SHT_DAT_DPRT,SHT_DAT_PIN); THSensDelay() #define SHT_LOW Clrb(SHT_DAT_PORT,SHT_DAT_PIN); Setb(SHT_DAT_DPRT,SHT_DAT_PIN) #define SHT_CLK1 THSensDelay(); Setb(SHT_CLK_PORT,SHT_CLK_PIN); THSensDelay() #define SHT_CLK0 THSensDelay(); Clrb(SHT_CLK_PORT,SHT_CLK_PIN); THSensDelay() void THSensStart() { uint8_t volatile i; SHT_RELES; for (i=0; i<20; i++) //Reset connection { SHT_CLK1; SHT_CLK0; } SHT_CLK1; SHT_LOW; SHT_CLK0; SHT_CLK1; SHT_RELES; SHT_CLK0; } void THSensSendBit(uint8_t dat) { if (dat) { SHT_RELES; } else { SHT_LOW; } SHT_CLK1; SHT_CLK0; } uint8_t THSensSendByte(uint8_t dat) //Return 1 when got ACK { uint8_t i,ack; ack = 0; for (i=0; i<8; i++) { THSensSendBit(Rdb(dat,7-i)); //Send MSB first } SHT_RELES; SHT_CLK1; if (SHT_RD == SHT_ACK) ack = 1; SHT_CLK0; return (ack); } void THSensRecvBit(uint8_t bitnum) { SHT_CLK1; if (SHT_RD) Setb(sht_dat_buf,bitnum); SHT_CLK0; } void THSensRecvByte(uint8_t ack) { uint8_t i; sht_dat_buf = 0; for (i=0; i<8; i++) { THSensRecvBit(7-i); //Recv MSB first } if (ack) { SHT_LOW; } else { SHT_RELES; } SHT_CLK1; SHT_CLK0; SHT_RELES; } void THSensInit() { Setb(SHT_CLK_DPRT,SHT_CLK_PIN); Clrb(SHT_CLK_PORT,SHT_CLK_PIN); SHT_RELES; } uint8_t THSensGet(uint8_t cmd) { uint16_t i; uint8_t valid = 0; THSensStart(); if (THSensSendByte(cmd)) { THSensDelay(); while (SHT_RD != 0); THSensDelay(); for (i=0; i<3; i++) { THSensRecvByte(1); sht_dat[i] = sht_dat_buf; } SHT_RELES; valid = 1; } return (valid); } uint8_t THSensSendCMD(uint8_t cmd) { uint8_t valid = 0; THSensStart(); if (THSensSendByte(cmd)) valid = 1; return (valid); } uint8_t THSensRecvDat() { uint8_t i; uint8_t got_data = 0; if (SHT_RD == 0) { THSensDelay(); for (i=0; i<3; i++) { THSensRecvByte(1); sht_dat[i] = sht_dat_buf; } SHT_RELES; got_data = 1; } return (got_data); } uint8_t THSensGetTemp() { return (THSensGet(SHT_TEMP_CMD)); } uint8_t THSensGetHumi() { return (THSensGet(SHT_HUMI_CMD)); } void THSensTest() { if (THSensGetTemp()) { THSensTempConv(); //If temperature = 30.50 //now sht_dat[0] = 30 //and sht_dat[1] = 50 //Use them as you wish!!! } } #endif