|
@@ -2,107 +2,173 @@
|
|
|
#include "i2c.h"
|
|
|
|
|
|
/* Defines */
|
|
|
-#define I2C_ADDR 0x70
|
|
|
+#define AHT_I2C_ADDR 0x70
|
|
|
|
|
|
-#define CMD_INIT 0xe1
|
|
|
-#define CMD_MEASURE 0xac
|
|
|
-#define CMD_SRESET 0xba
|
|
|
+#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 0x04
|
|
|
+#define STATUS_CAL 0x08
|
|
|
+#define STATUS_CALB 0x18
|
|
|
|
|
|
-aht10_st_t AHT10_Init(void)
|
|
|
+/* Functions prototypes */
|
|
|
+extern void tdelay_ms(uint16_t msek);
|
|
|
+uint8_t Calc_CRC8(uint8_t *message, uint8_t Num);
|
|
|
+aht20_st_t JH_Reset_REG(uint8_t addr);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Initialization
|
|
|
+ */
|
|
|
+aht20_st_t AHT20_Init(void)
|
|
|
{
|
|
|
i2c_status_t res;
|
|
|
+ uint8_t data;
|
|
|
+
|
|
|
+ // Just powered on, it takes time for the product chip to be ready internally,
|
|
|
+ // the delay is 100~500ms, and 500ms is recommended
|
|
|
+ tdelay_ms(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();
|
|
|
|
|
|
- res = I2C_WriteByte(I2C_ADDR);
|
|
|
+ res = I2C_WriteByte(AHT_I2C_ADDR);
|
|
|
if (res != I2C_Ret_OK) {
|
|
|
- return AHT10_St_Err;
|
|
|
+ return AHT_St_Err;
|
|
|
}
|
|
|
|
|
|
- res = I2C_WriteByte(CMD_SRESET);
|
|
|
+ res = I2C_WriteByte(CMD_GET_STATUS);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* get one byte with NACK */
|
|
|
+ res = I2C_ReadByte(&data, 1);
|
|
|
if (res != I2C_Ret_OK) {
|
|
|
- return AHT10_St_Err;
|
|
|
+ return AHT_St_Err;
|
|
|
}
|
|
|
|
|
|
I2C_Stop();
|
|
|
|
|
|
- return AHT10_St_OK;
|
|
|
+ if ((data & 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ tdelay_ms(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ return AHT_St_OK;
|
|
|
}
|
|
|
|
|
|
-aht10_st_t AHT10_SoftReset(void)
|
|
|
+aht20_st_t AHT20_SoftReset(void)
|
|
|
{
|
|
|
i2c_status_t res;
|
|
|
|
|
|
I2C_Start();
|
|
|
|
|
|
- res = I2C_WriteByte(I2C_ADDR);
|
|
|
+ res = I2C_WriteByte(AHT_I2C_ADDR);
|
|
|
if (res != I2C_Ret_OK) {
|
|
|
- return AHT10_St_Err;
|
|
|
+ return AHT_St_Err;
|
|
|
}
|
|
|
|
|
|
res = I2C_WriteByte(CMD_SRESET);
|
|
|
if (res != I2C_Ret_OK) {
|
|
|
- return AHT10_St_Err;
|
|
|
+ return AHT_St_Err;
|
|
|
}
|
|
|
|
|
|
I2C_Stop();
|
|
|
|
|
|
- return AHT10_St_OK;
|
|
|
+ return AHT_St_OK;
|
|
|
}
|
|
|
|
|
|
-aht10_st_t AHT10_StartMeasure(void)
|
|
|
+aht20_st_t AHT20_StartMeasure(void)
|
|
|
{
|
|
|
i2c_status_t res;
|
|
|
|
|
|
I2C_Start();
|
|
|
|
|
|
- res = I2C_WriteByte(I2C_ADDR);
|
|
|
+ res = I2C_WriteByte(AHT_I2C_ADDR);
|
|
|
if (res != I2C_Ret_OK) {
|
|
|
- return AHT10_St_Err;
|
|
|
+ return AHT_St_Err;
|
|
|
}
|
|
|
|
|
|
res = I2C_WriteByte(CMD_MEASURE);
|
|
|
if (res != I2C_Ret_OK) {
|
|
|
- return AHT10_St_Err;
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_WriteByte(CMD_MEASURE_CTL);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_WriteByte(CMD_MEASURE_NOP);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
}
|
|
|
|
|
|
I2C_Stop();
|
|
|
|
|
|
- return AHT10_St_OK;
|
|
|
+ return AHT_St_OK;
|
|
|
}
|
|
|
|
|
|
-aht10_st_t AHT10_GetData(aht10_t * data)
|
|
|
+aht20_st_t AHT20_GetData(aht20_t * data)
|
|
|
{
|
|
|
i2c_status_t res;
|
|
|
|
|
|
I2C_Start();
|
|
|
|
|
|
/* Send I2C read addr */
|
|
|
- res = I2C_WriteByte(I2C_ADDR | 0x1);
|
|
|
+ res = I2C_WriteByte(AHT_I2C_ADDR | 0x1);
|
|
|
if (res != I2C_Ret_OK) {
|
|
|
- return AHT10_St_Err;
|
|
|
+ return AHT_St_Err;
|
|
|
}
|
|
|
|
|
|
- /* Now read the value with NACK */
|
|
|
- uint8_t buf[6];
|
|
|
- res = I2C_ReadByte(buf, 0);
|
|
|
+ /* Now read the data */
|
|
|
+ uint8_t buf[8];
|
|
|
+ uint8_t rd, i;
|
|
|
+ /* read status and data */
|
|
|
+ for (i=0; i<6; i++) {
|
|
|
+ res = I2C_ReadByte(&rd, 0);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ buf[i] = rd;
|
|
|
+ }
|
|
|
+ /* read crc */
|
|
|
+ res = I2C_ReadByte(&rd, 1);
|
|
|
if (res != I2C_Ret_OK) {
|
|
|
- return AHT10_St_Err;
|
|
|
+ return AHT_St_Err;
|
|
|
}
|
|
|
+ buf[6] = rd;
|
|
|
|
|
|
I2C_Stop();
|
|
|
|
|
|
if ((buf[0] & STATUS_BUSY) != 0) {
|
|
|
- return AHT10_St_Bsy;
|
|
|
+ return AHT_St_Bsy;
|
|
|
}
|
|
|
+
|
|
|
/* Calculate values */
|
|
|
uint32_t result;
|
|
|
- //nt32_t result = {0};
|
|
|
|
|
|
/* Humidity = Srh * 100% / 2^20 */
|
|
|
result = buf[1];
|
|
@@ -112,7 +178,8 @@ aht10_st_t AHT10_GetData(aht10_t * data)
|
|
|
result |= buf[3];
|
|
|
result >>= 4;
|
|
|
result *= 100;
|
|
|
- result /= 1048576;
|
|
|
+ result += 524288;
|
|
|
+ result /= 10248576;
|
|
|
data->Humidity = (uint8_t)result;
|
|
|
|
|
|
/* Temperature = St * 200 / 2^20 - 50 */
|
|
@@ -122,9 +189,103 @@ aht10_st_t AHT10_GetData(aht10_t * data)
|
|
|
result <<= 8;
|
|
|
result |= buf[5];
|
|
|
result *= 200;
|
|
|
+ result += 524288;
|
|
|
result /= 1048576;
|
|
|
result -= 50;
|
|
|
data->Temperature = (int8_t)result;
|
|
|
|
|
|
- return AHT10_St_OK;
|
|
|
+ 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
|
|
|
+ */
|
|
|
+uint8_t Calc_CRC8(uint8_t *message, uint8_t Num)
|
|
|
+{
|
|
|
+ uint8_t i;
|
|
|
+ uint8_t byte;
|
|
|
+ uint8_t crc = 0xFF;
|
|
|
+
|
|
|
+ for (byte=0; byte<Num; byte++) {
|
|
|
+ crc ^= (message[byte]);
|
|
|
+ for (i=8; i>0; --i) {
|
|
|
+ if (crc & 0x80) {
|
|
|
+ crc = (crc << 1) ^ 0x31;
|
|
|
+ } else {
|
|
|
+ crc = (crc << 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return crc;
|
|
|
+}
|
|
|
+
|
|
|
+/* Reset register */
|
|
|
+aht20_st_t JH_Reset_REG(uint8_t addr) {
|
|
|
+ i2c_status_t res;
|
|
|
+ uint8_t Byte_first, Byte_second, Byte_third;
|
|
|
+
|
|
|
+ I2C_Start();
|
|
|
+ res = I2C_WriteByte(0x70); //It turned out to be 0x70
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_WriteByte(addr);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_WriteByte(0x00);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_WriteByte(0x00);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ I2C_Stop();
|
|
|
+
|
|
|
+ tdelay_ms(5); //Delay about 5ms
|
|
|
+ I2C_Start();
|
|
|
+ res = I2C_WriteByte(0x71);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_ReadByte(&Byte_first, 0);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_ReadByte(&Byte_second, 0);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_ReadByte(&Byte_third, 1);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ I2C_Stop();
|
|
|
+
|
|
|
+ tdelay_ms(10); //Delay about 10ms
|
|
|
+ I2C_Start();
|
|
|
+ res = I2C_WriteByte(0x70);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_WriteByte(0xB0|addr); //register command
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_WriteByte(Byte_second);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ res = I2C_WriteByte(Byte_third);
|
|
|
+ if (res != I2C_Ret_OK) {
|
|
|
+ return AHT_St_Err;
|
|
|
+ }
|
|
|
+ I2C_Stop();
|
|
|
+
|
|
|
+ return AHT_St_OK;
|
|
|
}
|