diff --git a/Hardware/aht20/aht20.c b/Hardware/aht20/aht20.c new file mode 100644 index 0000000..5bfab3a --- /dev/null +++ b/Hardware/aht20/aht20.c @@ -0,0 +1,163 @@ +/** + * @file aht20.c + * @author Myth + * @version 0.1 + * @date 2021.10.13 + * @brief AHT20 驱动 + */ + +#include "systick.h" + +#include "softi2c.h" + +#include "aht20.h" + +#define I2C_Start SoftI2C_Start(&aht20_i2c) +#define I2C_Stop SoftI2C_Stop(&aht20_i2c) +#define I2C_WriteByte(__byte__) SoftI2C_WriteByte(&aht20_i2c, __byte__) +#define I2C_ReadByte SoftI2C_ReadByte(&aht20_i2c) +#define I2C_Ack SoftI2C_Ack(&aht20_i2c) +#define I2C_NAck SoftI2C_NAck(&aht20_i2c) +#define I2C_WaitAck SoftI2C_WaitAck(&aht20_i2c) + +SoftI2C_TypeDef aht20_i2c; + +uint8_t AHT20_Read_Status(void); + +/** + * @brief 初始化 AHT20 + */ +void AHT20_Init(void) +{ + aht20_i2c.SDA_GPIO = AHT20_GPIO; + aht20_i2c.SDA_Pin = AHT20_SDA_PIN; + + aht20_i2c.SCL_GPIO = AHT20_GPIO; + aht20_i2c.SCL_Pin = AHT20_SCL_PIN; + + aht20_i2c.Delay_Time = 5; + + SoftI2C_Init(&aht20_i2c); + + Delay_ms(500); + + if (AHT20_Read_Status() & 0x18 == 0x18) + return; + + I2C_Start; + I2C_WriteByte(0x70); + I2C_WaitAck; + I2C_WriteByte(0xa8); + I2C_WaitAck; + I2C_WriteByte(0x00); + I2C_WaitAck; + I2C_WriteByte(0x00); + I2C_WaitAck; + I2C_Stop; + + Delay_ms(10); + + I2C_Start; + I2C_WriteByte(0x70); + I2C_WaitAck; + I2C_WriteByte(0xbe); + I2C_WaitAck; + I2C_WriteByte(0x08); + I2C_WaitAck; + I2C_WriteByte(0x00); + I2C_WaitAck; + I2C_Stop; + + Delay_ms(20); +} + +/** + * @brief 读取 AHT20 状态字 + * @retval 状态字 + */ +uint8_t AHT20_Read_Status(void) +{ + uint8_t data; + + I2C_Start; + + I2C_WriteByte(0x71); + I2C_WaitAck; + + data = I2C_ReadByte; + I2C_NAck; + + I2C_Stop; + + return data; +} + +/** + * @brief 读取 AHT20 数据 + * @param humi: 浮点数指针,储存湿度 + * @param temp: 浮点数指针,储存温度 + * @retval 读取成功返回 1,读取失败返回 0 + */ +uint8_t AHT20_Read(float *humi, float *temp) +{ + uint8_t byte1 = 0; + uint8_t byte2 = 0; + uint8_t byte3 = 0; + uint8_t byte4 = 0; + uint8_t byte5 = 0; + uint8_t byte6 = 0; + uint32_t data32 = 0; + + //发送 AC 指令请求数据 + I2C_Start; + I2C_WriteByte(0x70); + I2C_WaitAck; + I2C_WriteByte(0xac); + I2C_WaitAck; + I2C_WriteByte(0x33); + I2C_WaitAck; + I2C_WriteByte(0x00); + I2C_WaitAck; + I2C_Stop; + + Delay_ms(80); //延时 80ms,等待 AHT20 生成数据 + + uint16_t count = 0; + while (((AHT20_Read_Status() & 0x80) == 0x80)) //等待状态字最高位变为 1,说明数据准备完成 + { + Delay_ms(1); + if (count++ >= 100) + return 0; + } + + I2C_Start; + I2C_WriteByte(0x71); + I2C_WaitAck; + byte1 = I2C_ReadByte; //状态字 + I2C_Ack; + byte2 = I2C_ReadByte; //湿度数据 + I2C_Ack; + byte3 = I2C_ReadByte; //湿度数据 + I2C_Ack; + byte4 = I2C_ReadByte; //湿度/温度数据 + I2C_Ack; + byte5 = I2C_ReadByte; //温度数据 + I2C_Ack; + byte6 = I2C_ReadByte; //温度数据 + I2C_NAck; + I2C_Stop; + + data32 = (data32 | byte2) << 8; + data32 = (data32 | byte3) << 8; + data32 = (data32 | byte4); + data32 = data32 >> 4; + *humi = (float)data32 * 100.0 / 1024.0 / 1024.0; //湿度 + data32 = 0; + data32 = (data32 | byte4) << 8; + data32 = (data32 | byte5) << 8; + data32 = (data32 | byte6); + data32 = data32 & 0xfffff; + *temp = ((float)data32 * 200 * 10 / 1024 / 1024 - 500) / 10.0; //温度 + + return 1; +} diff --git a/Hardware/aht20/aht20.h b/Hardware/aht20/aht20.h new file mode 100644 index 0000000..649a521 --- /dev/null +++ b/Hardware/aht20/aht20.h @@ -0,0 +1,21 @@ +/** + * @file aht20.h + * @author Myth + * @version 0.1 + * @date 2021.10.13 + * @brief AHT20 驱动 + */ + +#ifndef __AHT20_H +#define __AHT20_H + +#include "sys.h" + +#define AHT20_GPIO GPIOB +#define AHT20_SDA_PIN GPIO_PIN_3 +#define AHT20_SCL_PIN GPIO_PIN_4 + +void AHT20_Init(void); +uint8_t AHT20_Read(float *humi, float *temp); + +#endif diff --git a/Project/SlaveNode.uvprojx b/Project/SlaveNode.uvprojx index 74d0666..90dc4f3 100644 --- a/Project/SlaveNode.uvprojx +++ b/Project/SlaveNode.uvprojx @@ -339,7 +339,7 @@ USE_HAL_DRIVER, STM32F103x6 - ..\Core;..\Libraries\HAL_Lib\Inc;..\Libraries\SoftSPI_HAL_Lib;..\Libraries\SoftI2C_HAL_Lib;..\User\Main;..\System\sys;..\System\systick;..\System\uart;..\Hardware\led + ..\Core;..\Libraries\HAL_Lib\Inc;..\Libraries\SoftSPI_HAL_Lib;..\Libraries\SoftI2C_HAL_Lib;..\User\Main;..\System\sys;..\System\systick;..\System\uart;..\Hardware\led;..\Hardware\aht20 @@ -693,6 +693,11 @@ 1 ..\Hardware\led\led.c + + aht20.c + 1 + ..\Hardware\aht20\aht20.c + diff --git a/User/Main/main.c b/User/Main/main.c index 92adde0..2e6dced 100644 --- a/User/Main/main.c +++ b/User/Main/main.c @@ -8,6 +8,7 @@ * @note 此版本实现功能: * 串口回显,回显时 PC13 上的 LED 闪烁 * 软件 I2C + * AHT20 温度湿度读取 * JTAG 已禁用,请使用 SWD 调试 */ @@ -18,6 +19,7 @@ #include "softi2c.h" #include "led.h" +#include "aht20.h" void Echo(uint8_t byte); @@ -36,39 +38,18 @@ int main(void) UART_BindReceiveHandle(COM1, Echo); //绑定 COM1 串口接收中断至 Echo 函数 - SoftI2C_TypeDef SoftI2C; - - SoftI2C.SDA_GPIO = GPIOB; - SoftI2C.SDA_Pin = GPIO_PIN_3; - SoftI2C.SCL_GPIO = GPIOB; - SoftI2C.SCL_Pin = GPIO_PIN_4; - SoftI2C.Delay_Time = 10; - - if (SoftI2C_Init(&SoftI2C) != HAL_OK) //初始化软件 I2C - { - Error_Handler(__FILE__, __LINE__); //错误处理 - } + AHT20_Init(); //初始化 AHT20 + float humi, temp; while (1) { //程序主循环 - SoftI2C_Start(&SoftI2C); + if (AHT20_Read(&humi, &temp)) //读取 AHT20 + printf("humi: %.1f temp: %.1f\n", humi, temp); + else + printf("fail to read AHT20.\n"); - SoftI2C_WriteByte(&SoftI2C, 0x10); - SoftI2C_WaitAck(&SoftI2C); - - SoftI2C_WriteByte(&SoftI2C, 0x22); - SoftI2C_WaitAck(&SoftI2C); - - SoftI2C_WriteByte(&SoftI2C, 0x33); - SoftI2C_WaitAck(&SoftI2C); - - SoftI2C_WriteByte(&SoftI2C, 0x44); - SoftI2C_WaitAck(&SoftI2C); - - SoftI2C_Stop(&SoftI2C); - - Delay_us(1000); + Delay_ms(500); } return 1;