#include "stm8s.h" #include "sensor.h" #include "i2c.h" #include "delay.h" /* Defines */ #define AHT_I2C_ADDR 0x38 #define CMD_GET_STATUS 0x71 #define CMD_INIT 0xbe #define CMD_MEASURE 0xac #define CMD_MEASURE_CTL 0x33 #define CMD_MEASURE_NOP 0x00 #define CMD_SRESET 0xba #define CMD_CALIBR1 0x1b #define CMD_CALIBR2 0x1c #define CMD_CALIBR3 0x1e #define STATUS_BUSY 0x80 #define STATUS_CMD 0x40 #define STATUS_CYC 0x20 #define STATUS_CAL 0x08 #define STATUS_CALB 0x18 /* Functions prototypes */ static uint8_t Calc_CRC8(uint8_t *message, uint8_t Num); static aht20_st_t JH_Reset_REG(uint8_t addr); /** * Initialization */ aht20_st_t AHT20_Init(void) { uint8_t buf[2]; // Just powered on, it takes time for the product chip to be ready internally, // the delay is 100~500ms, and 500ms is recommended Delay(500); // When power on, send 0x71 to read the status word for the first time, // and judge whether the status word is 0x18. i2c_start(); buf[0] = CMD_GET_STATUS; if (! i2c_send(AHT_I2C_ADDR, 1, buf)) { return AHT_St_Err; } /* get one byte */ if (! i2c_request(AHT_I2C_ADDR, 1, buf)) { return AHT_St_Err; } if ((buf[0] & STATUS_CALB) != STATUS_CALB) { //reinitialize registers aht20_st_t rest; rest = JH_Reset_REG(0x1b); if (rest != AHT_St_OK) { return AHT_St_Err; } rest = JH_Reset_REG(0x1c); if (rest != AHT_St_OK) { return AHT_St_Err; } rest = JH_Reset_REG(0x1e); if (rest != AHT_St_OK) { return AHT_St_Err; } Delay(1); } return AHT_St_OK; } aht20_st_t AHT20_SoftReset(void) { uint8_t buf[2]; i2c_start(); buf[0] = CMD_SRESET; if (! i2c_send(AHT_I2C_ADDR, 1, buf)) { return AHT_St_Err; } i2c_stop(); return AHT_St_OK; } aht20_st_t AHT20_StartMeasure(void) { uint8_t buf[4]; i2c_start(); buf[0] = CMD_MEASURE; buf[1] = CMD_MEASURE_CTL; buf[2] = CMD_MEASURE_NOP; if (! i2c_send(AHT_I2C_ADDR, 3, buf)) { return AHT_St_Err; } i2c_stop(); return AHT_St_OK; } aht20_st_t AHT20_GetData(aht20_t * data) { i2c_start(); /* Now read 7 bytes of data */ uint8_t buf[8]; if (! i2c_request(AHT_I2C_ADDR, 7, buf)) { return AHT_St_Err; } if ((buf[0] & STATUS_BUSY) != 0) { return AHT_St_Bsy; } /* Calculate values */ uint32_t result; /* Humidity = Srh * 100% / 2^20 */ result = buf[1]; result <<= 8; result |= buf[2]; result <<= 8; result |= buf[3]; result >>= 4; result *= 1000; result += 524288; result /= 256; result /= 256; result /= 16; data->Humidity = (uint16_t)result; /* Temperature = St * 200 / 2^20 - 50 */ result = buf[3] & 0xf; result <<= 8; result |= buf[4]; result <<= 8; result |= buf[5]; result *= 2000; result += 524288; result /= 256; result /= 256; result /= 16; data->Temperature = (int16_t)(result - 500); return AHT_St_OK; } /** * CRC check type: CRC8/MAXIM * Polynomial: X8+X5+X4+1 * Poly: 0011 0001 0x31 * When the high bit is placed in the back, it becomes 1000 1100 0x8c */ static uint8_t Calc_CRC8(uint8_t *message, uint8_t Num) { uint8_t i; uint8_t byte; uint8_t crc = 0xFF; for (byte=0; byte0; --i) { if (crc & 0x80) { crc = (crc << 1) ^ 0x31; } else { crc = (crc << 1); } } } return crc; } /* Reset register */ static aht20_st_t JH_Reset_REG(uint8_t addr) { uint8_t buf[4]; i2c_start(); buf[0] = addr; buf[1] = 0; buf[2] = 0; if (! i2c_send(AHT_I2C_ADDR, 3, buf)) { return AHT_St_Err; } i2c_stop(); Delay(5); //Delay about 5ms i2c_start(); if (! i2c_request(AHT_I2C_ADDR, 3, buf)) { return AHT_St_Err; } Delay(10); //Delay about 10ms i2c_start(); buf[0] = (0xB0|addr); if (! i2c_send(AHT_I2C_ADDR, 3, buf)) { return AHT_St_Err; } i2c_stop(); return AHT_St_OK; }