2.56 AHT20 温湿度传感器模块(来自格尔曼.斯帕罗的贡献)
2.56.1 模块来源
采购链接: https://m.tb.cn/h.522v7Ai?tk=CM7HdwuYarG
资料下载链接:https://pan.baidu.com/s/1yQz2bBw4QGDgH7kYElQzkQ 提取码:upxq 实物展示图
2.56.2 规格参数
工作电压:2.0~5.5v **工作电流:23****uA** 通信方式:标准 I2C 通讯引脚数量:4温度范围:-40~85℃湿度范围:0~100% 数据均来自于 AHT20 数据手册
2.56.3 模块原理
数据手册的前两节都是一些芯片的电气特性和简要介绍,跟我们移植模块的关系不大,不需要看,直接跳到第三节(3.接口定义),这里给出了 I2C 的硬件电路,由于我们的模块已经集成了上拉电阻,所以我们直接用杜邦线来连接梁山派和模块就行。不用考虑硬件电路。
第四节第五节分别给出了如何实现 I2C 通讯的时序图,是我们用软件方式实现 I2C 通讯的基础,手册给出的比较简陋,感兴趣的可去 B 站看看 I2C 的详细讲解。
第五节还给出了 AHT20 的 I2C 地址和命令字,模块的 AHT20 I2C 七位地址为 0x38,由此我们可以得出 AHT20 的写入八位地址为 0x70,读取八位地址为 0x71,具体地址的得出可以看看 I2C 的详细介绍。
得到 I2C 地址和手册给我们提供的开始测量命令后,我们按照手册的要求向 AHT20 发送测量命令。
发送完测命令后,由于 AHT20 测量需要时间,我们可以延时一段时间,等待测量结束,测量结束后我们按照手册的要求,读取七个字节,其中第一个字节为状态字,中间五个为温湿度数据,最后一个字节为 CRC 校验码。
获取到传感器数据后,我们按照手册的转换公式,对二进制数据进行处理,就可得到想要的十进制温湿度数据。
大概的移植过程就是这样,具体的细节需要认真看数据手册和代码,希望能对你有所帮助。
2.56.4 移植工程
AHT20 通讯方式为 I2C 通讯,我们只需要用梁山派实现 I2C 通讯,并按照数据手册对 AHT20 进行控制,就可以获取实时的温湿度数据。这里我给出的代码是基于软件 I2C,便于理解 I2C 通讯协议。
2.56.4.1 引脚选择
I2C 通讯引脚选择 PB8,PB9,对应梁山派的硬件 I2C0,方便切换软件 I2C 和硬件 I2C。
AHT20 | ######### 立创·梁山派 | ######### 接线图 |
---|
2.56.4.2 移植步骤
下面给出 AHT20 的驱动代码,包括软件 I2C 的实现,以及 AHT20 的控制。
#ifndef __AHT20_H
#define __AHT20_H
#include "gd32f4xx.h"
#include "systick.h"
//定义软件I2C延时
#define AHT20_I2C_Delay delay_1ms(1)
//@brief 定义软件I2C IO
#define AHT20_SCL_RCU RCU_GPIOB
#define AHT20_SCL_PORT GPIOB
#define AHT20_SCL_PIN GPIO_PIN_8
#define AHT20_SDA_RCU RCU_GPIOB
#define AHT20_SDA_PORT GPIOB
#define AHT20_SDA_PIN GPIO_PIN_9
//定义AHT20 I2C地址
#define AHT20_I2C_RECEIVE_ADDRESS 0x71
#define AHT20_I2C_SEND_ADDRESS 0x70
//定义软件I2C应答枚举类型
typedef enum
{
ACK_OK = 0,
ACK_NO = 1
} I2C_ACK;
//全局变量声明
extern uint8_t AHT20_data[7];
void AHT20_Init(void); //AHT20初始化
void AHT20_Detection_Start(void); //AHT20开始一次检测
#endif
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/********************************************************************************
* 测试硬件:立创·梁山派开发板GD32F470ZGT6 使用主频200Mhz 晶振25Mhz
* 版 本 号: V1.0
* 修改作者: LCKFB
* 修改日期: 2022年04月19日
* 功能介绍:
******************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:https://dri8c0qdfb.feishu.cn/docx/EGRVdxunnohkrNxItYTcrwAnnHe
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*********************************************************************************/
#include "AHT20.h"
uint8_t AHT20_data[7] = {0};
/******************************************************************
* 函 数 名 称:AHT20_I2C_IO_Init
* 函 数 说 明:AHT20软件I2C通讯IO口初始化
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
static void AHT20_I2C_IO_Init(void)
{
rcu_periph_clock_enable(AHT20_SCL_RCU);
rcu_periph_clock_enable(AHT20_SDA_RCU);
gpio_mode_set(AHT20_SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, AHT20_SCL_PIN);
gpio_output_options_set(AHT20_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_MAX, AHT20_SCL_PIN);
gpio_mode_set(AHT20_SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, AHT20_SDA_PIN);
gpio_output_options_set(AHT20_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_MAX, AHT20_SDA_PIN);
}
/******************************************************************
* 函 数 名 称:AHT20_I2C_Start
* 函 数 说 明:软件I2C产生开始信号
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
static void AHT20_I2C_Start(void)
{
gpio_bit_write(AHT20_SDA_PORT, AHT20_SDA_PIN, SET);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, SET);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SDA_PORT, AHT20_SDA_PIN, RESET);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, RESET);
AHT20_I2C_Delay;
}
/******************************************************************
* 函 数 名 称:AHT20_I2C_Stop
* 函 数 说 明:软件I2C产生结束信号
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
static void AHT20_I2C_Stop(void)
{
gpio_bit_write(AHT20_SDA_PORT, AHT20_SDA_PIN, RESET);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, SET);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SDA_PORT, AHT20_SDA_PIN, SET);
AHT20_I2C_Delay;
}
/******************************************************************
* 函 数 名 称:AHT20_I2C_Send_Ack
* 函 数 说 明:软件I2C产生应答信号
* 函 数 形 参:Ack=发送的应答
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
static void AHT20_I2C_Send_Ack(I2C_ACK Ack)
{
gpio_bit_write(AHT20_SDA_PORT, AHT20_SDA_PIN, (FlagStatus)Ack);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, SET);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, RESET);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SDA_PORT, AHT20_SDA_PIN, SET);
AHT20_I2C_Delay;
}
/******************************************************************
* 函 数 名 称:AHT20_I2C_Receive_Ack
* 函 数 说 明:软件I2C接收应答信号
* 函 数 形 参:无
* 函 数 返 回:ACK_OK=有应答,ACK_NO=无应答
* 作 者:LC
* 备 注:无
******************************************************************/
static I2C_ACK AHT20_I2C_Receive_Ack(void)
{
I2C_ACK Ack;
gpio_bit_write(AHT20_SDA_PORT, AHT20_SDA_PIN, SET);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, SET);
AHT20_I2C_Delay;
Ack = (I2C_ACK)gpio_input_bit_get(AHT20_SDA_PORT, AHT20_SDA_PIN);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, RESET);
AHT20_I2C_Delay;
return Ack;
}
/******************************************************************
* 函 数 名 称:AHT20_I2C_Send_Byte
* 函 数 说 明:软件I2C发送一个字节
* 函 数 形 参:Byte=发送的字节
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
static void AHT20_I2C_Send_Byte(uint8_t Byte)
{
uint8_t i;
I2C_ACK Ack = ACK_NO;
for (i = 0; i < 8; i ++)
{
gpio_bit_write(AHT20_SDA_PORT, AHT20_SDA_PIN, (FlagStatus)(Byte & (0x80 >> i)));
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, SET);
AHT20_I2C_Delay;
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, RESET);
AHT20_I2C_Delay;
}
Ack = AHT20_I2C_Receive_Ack();
if (Ack == ACK_OK)
{
}
else
{
}
}
/******************************************************************
* 函 数 名 称:AHT20_I2C_Receive_Byte
* 函 数 说 明:软件I2C接受的字节
* 函 数 形 参:Ack=接受完字节后给出的应答信号
* 函 数 返 回:接收到的字节
* 作 者:LC
* 备 注:无
******************************************************************/
static uint8_t AHT20_I2C_Receive_Byte(I2C_ACK Ack)
{
uint8_t Byte;
uint8_t i;
for (i = 8; i > 0; i--)
{
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, SET);
AHT20_I2C_Delay;
Byte |= (gpio_input_bit_get(AHT20_SDA_PORT, AHT20_SDA_PIN) << (i - 1));
gpio_bit_write(AHT20_SCL_PORT, AHT20_SCL_PIN, RESET);
AHT20_I2C_Delay;
}
AHT20_I2C_Send_Ack(Ack);
return Byte;
}
/******************************************************************
* 函 数 名 称:AHT20_Init
* 函 数 说 明:AHT20初始化
* 函 数 形 参:无
* 函 数 返 回:接收到的字节
* 作 者:LC
* 备 注:无
******************************************************************/
void AHT20_Init(void)
{
AHT20_I2C_IO_Init();
delay_1ms(100);
}
/******************************************************************
* 函 数 名 称:AHT20_Detection_Start
* 函 数 说 明:AHT20开始一次测量
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void AHT20_Detection_Start(void)
{
AHT20_I2C_Start();
AHT20_I2C_Send_Byte(AHT20_I2C_SEND_ADDRESS);
AHT20_I2C_Send_Byte(0xAC);
AHT20_I2C_Send_Byte(0x33);
AHT20_I2C_Send_Byte(0x00);
AHT20_I2C_Stop();
delay_1ms(80);
AHT20_I2C_Start();
AHT20_I2C_Send_Byte(AHT20_I2C_RECEIVE_ADDRESS);
AHT20_data[0] = AHT20_I2C_Receive_Byte(ACK_OK);
AHT20_data[1] = AHT20_I2C_Receive_Byte(ACK_OK);
AHT20_data[2] = AHT20_I2C_Receive_Byte(ACK_OK);
AHT20_data[3] = AHT20_I2C_Receive_Byte(ACK_OK);
AHT20_data[4] = AHT20_I2C_Receive_Byte(ACK_OK);
AHT20_data[5] = AHT20_I2C_Receive_Byte(ACK_OK);
AHT20_data[6] = AHT20_I2C_Receive_Byte(ACK_NO);
AHT20_I2C_Stop();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
2.56.5 移植验证
梁山派连接上 USB 转串口模块,连接好 AHT20 传感器,烧录程序后,电脑端打开任意串口助手软件,波特率设置为 115200,就可以在串口助手中看到温湿度数据。
移植成功工程文件