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;