/** * @file AHT20_ATY.c * * @param Project DEVICE_GENERAL_ATY_LIB * * @author ATY * * @copyright * - Copyright 2017 - 2023 MZ-ATY * - This code follows: * - MZ-ATY Various Contents Joint Statement - * * https://mengze.top/MZ-ATY_VCJS * - CC 4.0 BY-NC-SA - * * https://creativecommons.org/licenses/by-nc-sa/4.0/ * - Your use will be deemed to have accepted the terms of this statement. * * @brief Familiar functions of AHT20 for all embedded device * * @version * - 1_01_220804 > ATY * -# Preliminary version, first Release * - 1_02_220901 > ATY * -# Init tmp to zero, test AHT20_Init() ******************************************************************************** */ #ifndef __AHT20_ATY_C #define __AHT20_ATY_C #include "AHT20_ATY.h" /******************************* For user *************************************/ /******************************************************************************/ /** * @brief AHT20 soft reset */ void AHT20_SoftReset(void) { uint8_t temp_uint8 = 0; I2C_WriteReg(ATH20_ADDRESS, AHT20_SOFT_RST, &temp_uint8, 0); } /** * @brief read AHT20 status reg * @return reg data */ uint8_t AHT20_ReadStatusCmd(void) { uint8_t temp_uint8 = 0; I2C_ReadReg(ATH20_ADDRESS, AHT20_STATUS, &temp_uint8, 1); return temp_uint8; } /** * @brief AHT20 chip initialization */ void AHT20_IcInitCmd(void) { const uint8_t temp_uint8[2] = {0x08, 0x00}; // temp_uint8[0] = 0x00; // temp_uint8[1] = 0x00; // I2C_WriteReg(ATH20_ADDRESS, AHT20_NOR_MODE, temp_uint8, 2); // temp_uint8[0] = 0x08; // temp_uint8[1] = 0x00; I2C_WriteReg(ATH20_ADDRESS, AHT20_INIT, temp_uint8, 2); // I2C_WriteReg(ATH20_ADDRESS, 0xE1, temp_uint8, 2); } /** * @brief get AHT20 busy flag * @return busy flag: 1 - busy, 0 - leisure */ uint8_t AHT20_ReadBusyCmd(void) { uint8_t temp_uint8 = 0; temp_uint8 = AHT20_ReadStatusCmd(); return (temp_uint8 >> 7) & 0x01; } /** * @brief read AHT20 calibration enable * @return calibration state: 1 - calibrate done, 0 - not calibrated */ uint8_t AHT20_ReadCalEnableCmd(void) { uint8_t temp_uint8 = 0; temp_uint8 = AHT20_ReadStatusCmd(); return (temp_uint8 >> 3) & 0x01; } /** * @brief AHT20 measure command */ void AHT20_TrigMeasure(void) { const uint8_t temp_uint8[2] = {0x33, 0x00}; // temp_uint8[0] = 0x33; // temp_uint8[1] = 0x00; I2C_WriteReg(ATH20_ADDRESS, AHT20_TRIG_MEASURE, temp_uint8, 2); } /** * @brief AHT20 measure command * @param data_t group to save origin reg data */ void AHT20_ReadData(uint8_t* data_t) { I2C_Start(); I2C_WriteRegByte(ATH20_ADDRESS << 1 | 1); I2C_WaitAck(I2C_WAIT_ACK_TIME); data_t[0] = I2C_ReadByte(1); data_t[1] = I2C_ReadByte(1); data_t[2] = I2C_ReadByte(1); data_t[3] = I2C_ReadByte(1); data_t[4] = I2C_ReadByte(1); data_t[5] = I2C_ReadByte(0); I2C_Stop(); } /** * @brief reset AHT20 reg setting * @param addr reg address * @note generally not needed */ void AHT20_RegReset(uint8_t addr) { uint8_t temp_uint8[3] = {0}; temp_uint8[0] = 0x00; temp_uint8[1] = 0x00; temp_uint8[2] = 0x00; I2C_WriteReg(ATH20_ADDRESS, addr, temp_uint8, 2); DelayMs(5); I2C_ReadReg(ATH20_ADDRESS, AHT20_STATUS, temp_uint8, 3); DelayMs(10); I2C_WriteReg(ATH20_ADDRESS, 0xB0 | addr, temp_uint8 + 1, 2); } /** * @brief reset AHT20 reg setting * @note generally not needed */ void AHT20_RegInit(void) { AHT20_RegReset(0x1B); AHT20_RegReset(0x1C); AHT20_RegReset(0x1D); } /** * @brief AHT20 all initialize * @return errCode, 0: success, !0: error */ uint8_t AHT20_Init(void) { uint8_t errCount = 5; while(errCount--) { DelayMs(40); // wait time after power on if((AHT20_ReadStatusCmd() & 0x18) != 0x18) { AHT20_SoftReset(); AHT20_IcInitCmd(); AHT20_RegInit(); DelayMs(10); continue; } else break; } if(errCount == 0) return 1; errCount = 5; while(errCount--) { // check if calibrate over if(AHT20_ReadCalEnableCmd() == 0) { DelayMs(10); // if not calibrated, reset to retry AHT20_IcInitCmd(); // AHT20_SoftReset(); DelayMs(200); // time not sure } else break; } if(errCount == 0) return 2; return 0; } /* 0x1C 93 61 76 05 42 TEM:25.2HUM:57.5 */ /** * @brief read and split data to origin hum & tem * @param ht group to save hum & tem data * @return errCode, 0: success, !0: error */ uint8_t AHT20_ReadHT(uint32_t* ht) { uint8_t errCount = 5; uint8_t temp_uint8[6] = {0}; uint32_t RetuData = 0; AHT20_TrigMeasure(); while(errCount--) { // wait 75ms for measure finished, busy flag Bit7 set to 0 DelayMs(80); AHT20_ReadData(temp_uint8); if((temp_uint8[0] & 0x68) == 0x08) { // origin hum data RetuData = temp_uint8[1]; RetuData = (RetuData << 8) | temp_uint8[2]; RetuData = (RetuData << 8) | temp_uint8[3]; RetuData = RetuData >> 4; ht[0] = RetuData; // origin tem data RetuData = temp_uint8[3] & 0x0F; RetuData = (RetuData << 8) | temp_uint8[4]; RetuData = (RetuData << 8) | temp_uint8[5]; ht[1] = RetuData; return 0; } } return 1; } /** * @brief calculate result from 20bit origin data, RH=%, T=C * @param ht input origin data, always bigger than 0 * @param aht float data after calculate * @return errCode, 0: success, 1: out of range */ uint8_t AHT20_CalcResult(uint32_t* ht, float* aht) { aht[0] = (double)ht[0] * 100 / 1024 / 1024; // hum aht[1] = (double)ht[1] * 200 / 1024 / 1024; // tem // limit data range, RH = 0~100%, Temperature = -40~85C(+50) if((aht[0] >= 0) && (aht[0] <= 100) && (aht[1] >= 10) && (aht[1] <= 135)) return 0; else return 1; } /** * @brief calculate result from 20bit origin data, RH=%, T=C * @param ht data group to save th value * @return errCode, 0: success, !0: error */ uint8_t AHT20_InitFlag = 0; uint8_t AHT20_TemHumGet(uint16_t* ht) { if(AHT20_InitFlag == 0) { if(AHT20_Init() == 1) { AHT20_InitFlag = 2; // init fail } else { AHT20_InitFlag = 1; } } if(AHT20_InitFlag == 2) { #ifdef __DEBUG_AHT20_ATY printf("\r\n0xFF"); #endif /* __DEBUG_AHT20_ATY */ return 0xFF; } else if(AHT20_InitFlag == 1) { // Init success uint32_t tempHT_uint32[2] = {0}; float tempHT_f[2] = {0}; if(AHT20_ReadHT(tempHT_uint32) == 0) { if((tempHT_uint32[0] && tempHT_uint32[1]) != 0) { AHT20_CalcResult(tempHT_uint32, tempHT_f); ht[0] = ((tempHT_f[0] * 1000) + 5) / 10; ht[1] = ((tempHT_f[1] * 1000) + 5) / 10; #ifdef __DEBUG_AHT20_ATY printf("\r\nHum: %.2f - Tem: %.2f", tempHT_f[0], tempHT_f[1] - 50); #endif /* __DEBUG_AHT20_ATY */ } else { #ifdef __DEBUG_AHT20_ATY printf("\r\n0xFD"); #endif /* __DEBUG_AHT20_ATY */ return 0xFD; } } else { #ifdef __DEBUG_AHT20_ATY printf("\r\n0xFE"); #endif /* __DEBUG_AHT20_ATY */ return 0xFE; } } return 0; } #endif /* __AHT20_ATY_C */ /******************************** End Of File *********************************/