本文来源电子发烧友社区,作者:华仔stm32, 帖子地址:https://bbs.elecfans.com/jishu_2299452_1_1.html
在前面驱动OLED的前提下,驱动AHT20并显示到显示屏,是监测温湿度常用的手法。
1、在app目录下新建i2caht20文件夹,把oled_ssd1306.c以及oled_ssd1306.h拷贝到该目录下。
2、新建aht20.c、aht20.h,以及aht20.test.c,以及BUILD.gn三个文件。
3、aht20.c内容如下:
/*
* Copyright (C) 2021 HiHope Open Source Organization .
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*
* limitations under the License.
*/
#include "aht20.h"
#include
#include
#include
#include "hi_i2c.h"
#include "hi_errno.h"
#define AHT20_I2C_IDX HI_I2C_IDX_0
#define AHT20_STARTUP_TIME 20*1000 // 上电启动时间
#define AHT20_CALIBRATION_TIME 40*1000 // 初始化(校准)时间
#define AHT20_MEASURE_TIME 75*1000 // 测量时间
#define AHT20_DEVICE_ADDR 0x38
#define AHT20_READ_ADDR ((0x38<<1)|0x1)
#define AHT20_WRITE_ADDR ((0x38<<1)|0x0)
#define AHT20_CMD_CALIBRATION 0xBE // 初始化(校准)命令
#define AHT20_CMD_CALIBRATION_ARG0 0x08
#define AHT20_CMD_CALIBRATION_ARG1 0x00
/**
* 传感器在采集时需要时间,主机发出测量指令(0xAC)后,延时75毫秒以上再读取转换后的数据并判断返回的状态位是否正常。
* 若状态比特位[Bit7]为0代表数据可正常读取,为1时传感器为忙状态,主机需要等待数据处理完成。
**/
#define AHT20_CMD_TRIGGER 0xAC // 触发测量命令
#define AHT20_CMD_TRIGGER_ARG0 0x33
#define AHT20_CMD_TRIGGER_ARG1 0x00
// 用于在无需关闭和再次打开电源的情况下,重新启动传感器系统,软复位所需时间不超过20 毫秒
#define AHT20_CMD_RESET 0xBA // 软复位命令
#define AHT20_CMD_STATUS 0x71 // 获取状态命令
/**
* STATUS 命令回复:
* 1. 初始化后触发测量之前,STATUS 只回复 1B 状态值;
* 2. 触发测量之后,STATUS 回复6B: 1B 状态值 + 2B 湿度 + 4b湿度 + 4b温度 + 2B 温度
* RH = Srh / 2^20 * 100%
* T = St / 2^20 * 200 - 50
**/
#define AHT20_STATUS_BUSY_SHIFT 7 // bit[7] Busy indication
#define AHT20_STATUS_BUSY_MASK (0x1<#define AHT20_STATUS_BUSY(status) ((status & AHT20_STATUS_BUSY_MASK) >> AHT20_STATUS_BUSY_SHIFT)
#define AHT20_STATUS_MODE_SHIFT 5 // bit[6:5] Mode Status
#define AHT20_STATUS_MODE_MASK (0x3<#define AHT20_STATUS_MODE(status) ((status & AHT20_STATUS_MODE_MASK) >> AHT20_STATUS_MODE_SHIFT)
// bit[4] Reserved
#define AHT20_STATUS_CALI_SHIFT 3 // bit[3] CAL Enable
#define AHT20_STATUS_CALI_MASK (0x1<#define AHT20_STATUS_CALI(status) ((status & AHT20_STATUS_CALI_MASK) >> AHT20_STATUS_CALI_SHIFT)
// bit[2:0] Reserved
#define AHT20_STATUS_RESPONSE_MAX 6
#define AHT20_RESOLUTION (1<<20) // 2^20
#define AHT20_MAX_RETRY 10
static uint32_t AHT20_Read(uint8_t* buffer, uint32_t buffLen)
{
hi_i2c_data data = { 0 };
data.receive_buf = buffer;
data.receive_len = buffLen;
uint32_t retval = hi_i2c_read(AHT20_I2C_IDX, AHT20_READ_ADDR, &data);
if (retval != HI_ERR_SUCCESS) {
printf("I2cRead() failed, %0X!n", retval);
return retval;
}
return HI_ERR_SUCCESS;
}
static uint32_t AHT20_Write(uint8_t* buffer, uint32_t buffLen)
{
hi_i2c_data data = { 0 };
data.send_buf = buffer;
data.send_len = buffLen;
uint32_t retval = hi_i2c_write(AHT20_I2C_IDX, AHT20_WRITE_ADDR, &data);
if (retval != HI_ERR_SUCCESS) {
printf("I2cWrite(%02X) failed, %0X!n", buffer[0], retval);
return retval;
}
return HI_ERR_SUCCESS;
}
// 发送获取状态命令
static uint32_t AHT20_StatusCommand(void)
{
uint8_t statusCmd[] = { AHT20_CMD_STATUS };
return AHT20_Write(statusCmd, sizeof(statusCmd));
}
// 发送软复位命令
static uint32_t AHT20_ResetCommand(void)
{
uint8_t resetCmd[] = {AHT20_CMD_RESET};
return AHT20_Write(resetCmd, sizeof(resetCmd));
}
// 发送初始化校准命令
static uint32_t AHT20_CalibrateCommand(void)
{
uint8_t clibrateCmd[] = {AHT20_CMD_CALIBRATION, AHT20_CMD_CALIBRATION_ARG0, AHT20_CMD_CALIBRATION_ARG1};
return AHT20_Write(clibrateCmd, sizeof(clibrateCmd));
}
// 读取温湿度值之前, 首先要看状态字的校准使能位Bit[3]是否为 1(通过发送0x71可以获取一个字节的状态字),
// 如果不为1,要发送0xBE命令(初始化),此命令参数有两个字节, 第一个字节为0x08,第二个字节为0x00。
uint32_t AHT20_Calibrate(void)
{
uint32_t retval = 0;
uint8_t buffer[AHT20_STATUS_RESPONSE_MAX];
memset(&buffer, 0x0, sizeof(buffer));
retval = AHT20_StatusCommand();
if (retval != HI_ERR_SUCCESS) {
return retval;
}
retval = AHT20_Read(buffer, sizeof(buffer));
if (retval != HI_ERR_SUCCESS) {
return retval;
}
if (AHT20_STATUS_BUSY(buffer[0]) || !AHT20_STATUS_CALI(buffer[0])) {
retval = AHT20_ResetCommand();
if (retval != HI_ERR_SUCCESS) {
return retval;
}
usleep(AHT20_STARTUP_TIME);
retval = AHT20_CalibrateCommand();
usleep(AHT20_CALIBRATION_TIME);
return retval;
}
return HI_ERR_SUCCESS;
}
// 发送 触发测量 命令,开始测量
uint32_t AHT20_StartMeasure(void)
{
uint8_t triggerCmd[] = {AHT20_CMD_TRIGGER, AHT20_CMD_TRIGGER_ARG0, AHT20_CMD_TRIGGER_ARG1};
return AHT20_Write(triggerCmd, sizeof(triggerCmd));
}
// 接收测量结果,拼接转换为标准值
uint32_t AHT20_GetMeasureResult(float* temp, float* humi)
{
uint32_t retval = 0, i = 0;
if (temp == NULL || humi == NULL) {
return HI_ERR_FAILURE;
}
uint8_t buffer[AHT20_STATUS_RESPONSE_MAX];
memset(&buffer, 0x0, sizeof(buffer));
retval = AHT20_Read(buffer, sizeof(buffer)); // recv status command result
if (retval != HI_ERR_SUCCESS) {
return retval;
}
for (i = 0; AHT20_STATUS_BUSY(buffer[0]) && i < AHT20_MAX_RETRY; i++) {
// printf("AHT20 device busy, retry %d/%d!rn", i, AHT20_MAX_RETRY);
usleep(AHT20_MEASURE_TIME);
retval = AHT20_Read(buffer, sizeof(buffer)); // recv status command result
if (retval != HI_ERR_SUCCESS) {
return retval;
}
}
if (i >= AHT20_MAX_RETRY) {
printf("AHT20 device always busy!rn");
return HI_ERR_SUCCESS;
}
uint32_t humiRaw = buffer[1];
humiRaw = (humiRaw << 8) | buffer[2];
humiRaw = (humiRaw << 4) | ((buffer[3] & 0xF0) >> 4);
*humi = humiRaw / (float)AHT20_RESOLUTION * 100;
uint32_t tempRaw = buffer[3] & 0x0F;
tempRaw = (tempRaw << 8) | buffer[4];
tempRaw = (tempRaw << 8) | buffer[5];
*temp = tempRaw / (float)AHT20_RESOLUTION * 200 - 50;
// printf("humi = %05X, %f, temp= %05X, %frn", humiRaw, *humi, tempRaw, *temp);
return HI_ERR_SUCCESS;
}
)<>)<>)<>
4、aht20.h内容如下:
/*
* Copyright (C) 2021 HiHope Open Source Organization .
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*
* limitations under the License.
*/
#ifndef AHT20_H
#define AHT20_H
#include
uint32_t AHT20_Calibrate(void);
uint32_t AHT20_StartMeasure(void);
uint32_t AHT20_GetMeasureResult(float* temp, float* humi);
#endif // AHT20_H
5、aht20_test.c内容如下:
/*
* Copyright (C) 2021 HiHope Open Source Organization .
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*
* limitations under the License.
*/
#include "aht20.h"
#include
#include
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "hi_gpio.h"
#include "hi_io.h"
#include "hi_i2c.h"
#include "oled_ssd1306.h"
void Aht20TestTask(void* arg)
{
(void) arg;
uint32_t retval = 0;
char str_temp[12];
char str_Humi[12];
hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA);
hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL);
hi_i2c_init(HI_I2C_IDX_0, 400*1000);
OledInit();
OledFillScreen(0x00);
OledShowString(26, 0, "AHT20-TEST!", FONT8x16);
retval = AHT20_Calibrate();
printf("AHT20_Calibrate: %drn", retval);
while (1) {
float temp = 0.0, humi = 0.0;
retval = AHT20_StartMeasure();
printf("AHT20_StartMeasure: %drn", retval);
retval = AHT20_GetMeasureResult(&temp, &humi);
sprintf(str_temp,"TEMP:%.2f",temp);
sprintf(str_Humi,"HUMI:%.2f",humi);
printf("AHT20_GetMeasureResult: %d, temp = %.2f, humi = %.2frn", retval, temp, humi);
OledShowString(26,2,str_temp,FONT8x16);
OledShowString(26,4,str_Humi,FONT8x16);
sleep(1);
}
}
void Aht20Test(void)
{
osThreadAttr_t attr;
attr.name = "Aht20Task";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 4096;
attr.priority = osPriorityNormal;
if (osThreadNew(Aht20TestTask, NULL, &attr) == NULL) {
printf("[Aht20Test] Failed to create Aht20TestTask!n");
}
}
APP_FEATURE_INIT(Aht20Test);
7、BUILD.gn:
#Copyright (C) 2021 HiHope Open Source Organization .
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#
#limitations under the License.
static_library("i2cd_emo") {
sources = [
"aht20_test.c",
"aht20.c",
"oled_ssd1306.c"
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/hisilicon/hispark_pegasus/sdk_liteos/include"
]
}
8、修改app/BUILD.gn如下:
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [
"i2caht20:i2cd_emo",
]
}
然后就可以编译下载了。
运行效果如下图:
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
wi-fi
+关注
关注
14文章
2112浏览量
124330 -
HarmonyOS
+关注
关注
79文章
1967浏览量
30025 -
HiSpark
+关注
关注
1文章
156浏览量
6904
发布评论请先 登录
相关推荐
Wi-Fi 8要来了!未来Wi-Fi技术演进方向揭秘
产品销售中,虽然Wi-Fi 7产品的销量份额快速从年初的个位数百分比增长至14%,但Wi-Fi 6产品的销量份额依然稳定在60%左右。如果从存量设备来看,那么Wi-Fi 7路由器的占比将远远小于这个数。 智能手机等终端设备已
飞凌嵌入式ElfBoard ELF 1板卡-使用AHT20进行环境监测之AHT20传感器介绍
i2c接口的的AHT20温湿度传感器。i2c硬件原理见硬件手册,通信协议见3.2.2小节,我们前面这些章节已经介绍了i2c的基本通信原理,本节我们主要关注的是AHT20作为i2c从设备,是如何与ELF
发表于 11-26 09:36
Wi-Fi 7与Wi-Fi 6E有什么区别
也许很多人还在考虑是否要将使用的Wi-Fi设备升级到Wi-Fi 6或Wi-Fi 6E,而这些标准的继任者却已经开始“登堂入室”了。Wi-Fi 7是新一代
库房温湿度自动监测系统
对库房内温湿度的实时、自动监测。在线实时采集库房内的温湿度数据,无线传输并汇总到管理平台上,进行存储、分析、报警等操作,随时查看库房内的温湿度情况,以便管理员及时调控仓储库房环境情况,
想要准确地测量环境温湿度?温湿度传感器是关键!
温湿度是生产生活中最重要的环境指标之一,不仅人需要在适宜的温湿度条件下保持良好的精神状态和敏捷的思维,食品、药品、各种仪器设备等都对环境温湿度有特殊的要求。基于对环境温湿度的要求,
验证物联网Wi-Fi HaLow用例的MM6108-EKH08开发套件来啦
验证物联网Wi-Fi HaLow用例的MM6108-EKH08开发套件来啦 MM6108-EKH08开发套件专为验证物联网Wi-Fi HaLow用例而设计。该
学习笔记|如何用Go程序采集温湿度传感器数据
在共创社内部的交流中,先前有一位成员展示了如何借助C语言来实现对AHT20温湿度传感器数据的读取。这一实例触发了另一位共创官的灵感,他决定采纳Go语言重新构建这一数据采集流程。接下来,我们将详细解析
温湿度传感器工作原理 温湿度传感器的接线方法
温湿度传感器是一种用于测量环境温度和相对湿度的装置。它通常用于工业、农业、气象、室内空调等领域。本文将详细介绍温湿度传感器的工作原理和接线方法。 一、温湿度传感器的工作原理
Wi-Fi HaLow和传统Wi-Fi的区别
HaLow和传统Wi-Fi之间的区别,并探讨其各自的优缺点。 Wi-Fi HaLow是一种低功耗、长范围的无线网络标准。与传统的Wi-Fi标准相比
BT Wi-Fi模式是否可以通过ModustoolBox对套件进行编程来实现?
想配置用于分析 CYW43439 的 CY8CPROTO-062S2-43439 原型开发套件。
浏览文档我无法弄清楚如何在不同的 Wi-Fi 和蓝牙模式(电源模式、连接模式等)下配置套件。
在
发表于 01-22 06:19
【ELF 1开发板试用】板载资源测试4:体验温湿度传感器
命令行操作界面。 3、六轴传感器测试(1)温湿度传感器器AHT20在开发板的位置如图。 (2)将开发板平放,命令行执行elf1_cmd_aht20,显示当前
发表于 12-18 11:09
Wi-Fi 6和Wi-Fi 5之间有哪些区别呢?
Wi-Fi 6和Wi-Fi 5之间有哪些区别呢? Wi-Fi 6和Wi-Fi 5是无线局域网标准的两个版本,它们之间存在很多区别。Wi-Fi
评论