本文來源電子發燒友社區,作者:華仔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 = [
"http://utils/native/lite/include",
"http://kernel/liteos_m/components/cmsis/2.0",
"http://base/iot_hardware/peripheral/interfaces/kits",
"http://device/hisilicon/hispark_pegasus/sdk_liteos/include"
]
}
8、修改app/BUILD.gn如下:
import("http://build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [
"i2caht20:i2cd_emo",
]
}
然后就可以編譯下載了。
運行效果如下圖:

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
wi-fi
+關注
關注
15文章
2424瀏覽量
129553 -
HarmonyOS
+關注
關注
80文章
2153瀏覽量
36053 -
HiSpark
+關注
關注
1文章
156瀏覽量
7757
發布評論請先 登錄
相關推薦
熱點推薦
Nordic發布nRF7002 EBII 開發板, 支持Wi-Fi 6, 解鎖nRF54L新玩法
了 Wi-Fi 6 功能,幫助開發人員創建高性能、高能效的Wi-Fi 6 物聯網解決方案。
基于 Nordic 的 nRF7002 Wi-Fi 協同 IC,nRF7002 EBII幫助 采用
發表于 12-10 11:58
【上海晶珩睿莓1開發板試用體驗】Home Assistant 物聯網溫濕度計
AHT10 傳感器;
環境配置:安裝 Python 工具庫,包括 i2c-tools 和 smbus2 ;
AHT10 驅動:驅動 AHT
發表于 08-18 13:55
功耗創新低!涂鴉產品級Zigbee 3.0溫濕度計開發包,開箱即用、完全開源
低功耗類設備,采用Zigbee3.0協議,待機電流低至幾個微安(uA),一節紐扣電池可持續工作長達1~2年,遠超Wi-Fi版續航時長(僅能維持2個月),是溫濕度類設
有沒有什么修復方法可以確保 AP 模式下的 Wi-Fi 和 BLE 連接同時正常工作?
我正在使用 CYBSYSKIT DEV 01 套件。我嘗試在 AP 模式下打開 Wi-Fi 并宣傳 BLE。我可以宣傳 SoftAP 和 BLE。但是,我無法從中央設備連接到 BLE。它可以立即連接
發表于 07-17 06:13
STM32+esp8266連接機智云,上傳溫濕度數據并控制繼電器開關(平臺配置、代碼生成、代碼移植)
代碼,并通過手機APP進行設備控制。元器件準備在開始之前,您需要準備以下硬件元器件:1.STM32開發板2.ESP8266Wi-Fi模塊3.溫濕度傳感器(如DHT1
Wi-Fi 8:開啟極高可靠性 (UHR) 連接的新紀元——1
英國作家狄更斯在《雙城記》的開頭寫道:“這是最好的時代,也是最壞的時代。”
這句話若套用在現今Wi-Fi 的市場現狀,何嘗不是驚人的相似?
怎么說呢?Wi-Fi 從被發明至今已經經過了20多年的迭代
發表于 06-13 11:09
溫濕度變送器功能有哪些?一文詳細解析
,也能通過電腦、手機等設備實時查看溫濕度數據。對于一些需要實時監控的場所,如機房、醫院的藥品倉庫等,遠程監控功能能夠讓管理人員及時發現異常情況并采取措施。
三、報警功能
為了確保環境溫濕度處于合適的范圍
發表于 06-03 10:56
智能倉儲:溫濕度監控方案應用
隨著倉儲環境要求提高,溫濕度監控對保障貨物品質至關重要。本文介紹一個工廠倉庫溫濕度監控方案,利用溫濕度變送器、LoRa技術和智能監測平臺,為倉庫業主提供高效、可靠的監測解決方案。倉庫溫濕度
基于 Wi-Fi 的定位服務
以下捕獲使用 location_wifi_get 函數請求 Wi-Fi 定位服務。該事件的總功耗為 125.85mC,日志顯示精確度為 30.0m。
Got location:
method
發表于 04-17 15:16
nRF Cloud Wi-Fi 定位服務
、Predictive-GPS、Single-Cell、Multi-Cell 和 Wi-Fi 定位。通過利用 nRF Cloud 的優化定位算法,基于 Nordic SoC 和 模組的產品可在定位用例
發表于 04-17 15:07
Wi-Fi 定位服務
定位服務提供商維護。
通過查找數據庫中的匹配模式并計算信號強度來估計位置的算法。
當設備查詢定位服務時,它會提供它能看到的所有 Wi-Fi 網絡的數據。該服務會在其數據庫中查找這些網絡,找到相關位置,并根據相似性和信號強度估算設
發表于 04-17 15:01
嵌入式學習-飛凌嵌入式ElfBoard ELF 1板卡-I2C設備驅動之I2C驅動之溫濕度傳感器
例程代碼路徑:ELF 1開發板資料包\\03-例程源碼\\03-2 驅動例程源碼\\07_I2C驅動-aht20下面編寫一個溫濕度傳感器的驅動
發表于 04-15 10:41
飛凌嵌入式ElfBoard ELF 1板卡-I2C設備驅動之I2C驅動之溫濕度傳感器
例程代碼路徑:ELF 1開發板資料包\\03-例程源碼\\03-2 驅動例程源碼\\07_I2C驅動-aht20下面編寫一個溫濕度傳感器的驅動
發表于 04-15 10:24
【HarmonyOS HiSpark Wi-Fi IoT 套件試用連載】驅動AHT20并顯示溫濕度
評論