4 #include <linux/i2c-dev.h>
7 #include <unistd.h> /* add by paulerr*/
10 #define CHIP "/dev/i2c-0"
11 #define CHIP_ADDR 0x40 //HTU21D地址
12 #define READ_TEMP 0XE3 //温度转换命令
13 #define READ_HUM 0XE5 //湿度转换命令
15 /* More info: https://github.com/kingmacth/Openwet-SDK/tree/master/package/HTU21D */
17 unsigned char HTU21D_Check_CRC(unsigned short int message_from_sensor,unsigned char check_value_from_sensor);
22 printf("hello,this is HTU21D tester \n");
23 int fd =open(CHIP, O_RDWR);
25 printf("open"CHIP"failed \n");
29 if (ioctl(fd,I2C_SLAVE_FORCE, CHIP_ADDR) < 0) { /*设置芯片地址 */
30 printf("oictl:setslave address failed\n");
36 unsigned char rddata[3];
37 unsigned char rdaddr[2] = {0x10, 0}; /* 将要读取的数据在芯片中的偏移量 */
38 unsigned char TempAddr[2] = {0xe3, 0}; /* 发送E3读取温度 */
39 unsigned char HumAddr[2] = {0xE5, 0}; /* 发送E5读取湿度 */
40 unsigned short int tmp_dat,CRC_Result;
42 /*printf("inputa char you want to write to E2PROM\n");
44 printf("writereturn:%d, write data:%x\n", write(fd, wrbuf, 1), wrbuf[2]);
46 //printf("Read temp!\n",write(fd, TempAddr, 1)); /* 开启温度转换 */
47 write(fd, TempAddr, 1);
49 read(fd, &rddata, 3); //读取两字节温度一字节校验
53 tmp_dat=tmp_dat+rddata[1];
54 //printf("rddata:%x%02x,%x\n", rddata[0], rddata[1],rddata[2]);
55 CRC_Result=HTU21D_Check_CRC(tmp_dat,rddata[2]);
56 //printf("CRC=%x,%x\n",CRC_Result ,tmp_dat);//CRC校验
59 Temp=(tmp_dat*175.72)/65536-46.85;
60 printf("Temp=%.2f\n",Temp);
62 //printf("Read hum!\n",write(fd, HumAddr, 1)); /* 开启湿度转换 */
63 write(fd, HumAddr, 1);
65 read(fd, &rddata, 3); //读取两字节湿度一字节校验
69 tmp_dat=tmp_dat+rddata[1];
70 //printf("rddata:%x%02x,%x\n", rddata[0], rddata[1],rddata[2]);
71 CRC_Result=HTU21D_Check_CRC(tmp_dat,rddata[2]);
72 //printf("CRC=%x,%x\n",CRC_Result ,tmp_dat);//CRC校验
75 Temp=(tmp_dat*125)/65536-6;
76 printf("Hum=%.2f%%RH\n",Temp);
86 //**************************************************************************************************************
87 //两个参数一个是传感器的源数据,另一个是传感器得出的CRC校验值
89 //From: http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html
90 //POLYNOMIAL = 0x0131 = x^8 + x^5 + x^4 + 1 : http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks
91 #define SHIFTED_DIVISOR 0x988000 //This is the 0x0131 polynomial shifted to farthest left of three bytes
92 //**************************************************************************************************************
93 unsigned char HTU21D_Check_CRC(unsigned short int message_from_sensor,unsigned char check_value_from_sensor)
96 //Test cases from datasheet:
97 //message = 0xDC, checkvalue is 0x79
98 //message = 0x683A, checkvalue is 0x7C
99 //message = 0x4E85, checkvalue is 0x6B
100 unsigned int remainder = (unsigned int)message_from_sensor << 8; //Pad with 8 bits because we have to add in the check value
101 unsigned int divsor = (unsigned int)SHIFTED_DIVISOR;
102 remainder |= check_value_from_sensor; //Add on the check value
103 for (i = 0 ; i < 16 ; i++) //Operate on only 16 positions of max 24. The remaining 8 are our remainder and should be zero when we're done.
105 if( remainder & (unsigned int)1<<(23 - i) ) //Check if there is a one in the left position
107 divsor>>=1;//Rotatethedivsormax16timessothatwehave8bitsleftofaremainder
109 return(unsigned char)remainder;