目录

openharmony1.1.3-通过i2c进行温湿度采集

openharmony1.1.3 通过i2c进行温湿度采集

https://i-blog.csdnimg.cn/direct/1003a801cfeb4f2f9d391b4cc0debf16.png

温湿度传感器 也是挂载这个i2c总线上

初始化?

读数据

写数据

1.1.3 版本的i2c底层接口:

https://i-blog.csdnimg.cn/direct/bd8756faf2ea4546a6d18637b19f08cf.png

默认 系统没有开启i2c

CONFIG_I2C_SUPPORT is not set

CONFIG_I2C_SUPPORT = y

https://i-blog.csdnimg.cn/direct/a709e92369df4e4194de6cb27cdf200c.png

开启i2c

https://i-blog.csdnimg.cn/direct/4256dbb197c7488b976de46c232b9fb3.png

写一套通过i2c 读写温湿度的文件:

https://i-blog.csdnimg.cn/direct/aa7abe2a727d4ec7a430d0cd756f41c3.png

aht20.h:


#ifndef AHT20_H

#define AHT20_H



#include <stdbool.h>  // 提供 bool 类型

#include "iot_errno.h"  // 提供 IOT_SUCCESS/IOT_FAILURE

#include <stdint.h>



unsigned int AHT20_Init(void);

unsigned int AHT20_Calibrate(void);

unsigned int AHT20_SoftReset(void);

unsigned int AHT20_GetMeasureResult(float* temp, float* humi);



#endif  // AHT20_H

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 <stdio.h>

#include <string.h>



// OpenHarmony HAL层I2C头文件(替换原海思私有头文件)

#include "iot_i2c.h"

// 延时函数头文件

#include "hi_time.h"



// 传感器硬件参数

#define AHT20_I2C_IDX      0  // OpenHarmony标准I2C总线索引



// 传感器命令定义

#define AHT20_INIT_CMD        0xBE    // 初始化命令

#define AHT20_CALIBRATE_CMD   0xBA    // 校准命令

#define AHT20_MEASURE_CMD     0xAC    // 测量命令

#define AHT20_SOFT_RESET_CMD  0xBA    // 软复位命令















#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<<AHT20_STATUS_BUSY_SHIFT)

#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<<AHT20_STATUS_MODE_SHIFT)

#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<<AHT20_STATUS_CALI_SHIFT)

#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 bool g_aht20Initialized = false;



/**

 * @brief 内部函数:I2C读取数据(调用OpenHarmony HAL层接口)

 */

static unsigned int AHT20_I2C_Read(uint8_t* buffer, uint32_t buffLen) {

    if (buffer == NULL || buffLen == 0) {

        return IOT_FAILURE;

    }

    // 调用HAL层I2C读函数

    return IoTI2cRead(AHT20_I2C_IDX, AHT20_READ_ADDR, buffer, buffLen);

}



/**

 * @brief 内部函数:I2C写入数据(调用OpenHarmony HAL层接口)

 */

static unsigned int AHT20_I2C_Write(uint8_t* buffer, uint32_t buffLen) {

    if (buffer == NULL || buffLen == 0) {

        return IOT_FAILURE;

    }

    // 调用HAL层I2C写函数

    return IoTI2cWrite(AHT20_I2C_IDX, AHT20_WRITE_ADDR, buffer, buffLen);

}



/**

 * @brief 软件复位AHT20

 */

unsigned int AHT20_SoftReset(void) {

    uint8_t resetCmd = AHT20_SOFT_RESET_CMD;

    unsigned int retval = AHT20_I2C_Write(&resetCmd, 1);

    

    hi_udelay(20000);  // 复位后等待20ms

    if (retval != IOT_SUCCESS) {

        printf("AHT20 soft reset failed, err: %u\n", retval);

        return retval;

    }

    return IOT_SUCCESS;

}



/**

 * @brief 校准AHT20

 */

unsigned int AHT20_Calibrate(void) {

    uint8_t calCmd[3] = {AHT20_CALIBRATE_CMD, 0x00, 0x00};

    unsigned int retval = AHT20_I2C_Write(calCmd, 3);

    

    hi_udelay(30000);  // 校准等待30ms

    if (retval != IOT_SUCCESS) {

        printf("AHT20 calibrate failed, err: %u\n", retval);

        return retval;

    }

    return IOT_SUCCESS;

}



/**

 * @brief 初始化AHT20

 */

unsigned int AHT20_Init(void) {

    uint8_t initCmd[3] = {AHT20_INIT_CMD, 0x08, 0x00};

    unsigned int retval = 0;



    // 1. 软复位传感器

    retval = AHT20_SoftReset();

    if (retval != IOT_SUCCESS) {

        return retval;

    }



    // 2. 发送初始化命令

    hi_udelay(40000);  // 复位后等待40ms

    retval = AHT20_I2C_Write(initCmd, 3);

    if (retval != IOT_SUCCESS) {

        printf("AHT20 init cmd failed, err: %u\n", retval);

        return retval;

    }



    // 3. 标记初始化完成

    g_aht20Initialized = true;

    return IOT_SUCCESS;

}



/**

 * @brief 获取温湿度测量结果

 * @param temp 温度结果指针(单位:℃)

 * @param humi 湿度结果指针(单位:%RH)

 * @return 成功返回IOT_SUCCESS,失败返回对应错误码

 */

unsigned int AHT20_GetMeasureResult(float* temp, float* humi) {

    // 参数合法性检查

    if (temp == NULL || humi == NULL) {

        return IOT_FAILURE;

    }

    if (!g_aht20Initialized) {

        printf("AHT20 not initialized!\n");

        return IOT_FAILURE;

    }



    uint8_t measureCmd[3] = {AHT20_MEASURE_CMD, 0x33, 0x00};

    uint8_t dataBuf[6] = {0};

    unsigned int retval = 0;



    // 1. 发送测量命令

    retval = AHT20_I2C_Write(measureCmd, 3);

    if (retval != IOT_SUCCESS) {

        printf("AHT20 measure cmd failed, err: %u\n", retval);

        return retval;

    }



    // 2. 等待测量完成(最大80ms)

    hi_udelay(80000);



    // 3. 读取测量数据

    retval = AHT20_I2C_Read(dataBuf, 6);

    if (retval != IOT_SUCCESS) {

        printf("AHT20 read data failed, err: %u\n", retval);

        return retval;

    }



    // 4. 解析测量状态

    if ((dataBuf[0] & 0x80) != 0) {

        printf("AHT20 measure not ready!\n");

        return IOT_FAILURE;

    }



    // 5. 计算温湿度

    uint32_t humiRaw = ((uint32_t)dataBuf[1] << 12) | 

                       ((uint32_t)dataBuf[2] << 4) | 

                       ((dataBuf[3] & 0xF0) >> 4);

    *humi = (humiRaw / 1048576.0f) * 100.0f;



    uint32_t tempRaw = ((uint32_t)(dataBuf[3] & 0x0F) << 16) | 

                       ((uint32_t)dataBuf[4] << 8) | 

                       dataBuf[5];

    *temp = (tempRaw / 1048576.0f) * 200.0f - 50.0f;



    return IOT_SUCCESS;

}

#define AHT20_I2C_IDX      0  // OpenHarmony标准I2C总线索引  hi3861 就一条总线

AHT20第地址:

#define AHT20_DEVICE_ADDR   0x38
#define AHT20_READ_ADDR     ((0x38«1)|0x1)
#define AHT20_WRITE_ADDR    ((0x38«1)|0x0)

https://i-blog.csdnimg.cn/direct/5080fcad1188455f81e4473a5127abc4.png

**通I2C读写的方法:**这个是1.1.3 当中的方法 具体看i2c头文件的描述

/**
 * @brief 内部函数:I2C读取数据(调用OpenHarmony HAL层接口)
 /
static unsigned int AHT20_I2C_Read(uint8_t
buffer, uint32_t buffLen) {
    if (buffer == NULL || buffLen == 0) {
        return IOT_FAILURE;
    }
    // 调用HAL层I2C读函数
    return IoTI2cRead(AHT20_I2C_IDX, AHT20_READ_ADDR, buffer, buffLen);
}

/**
 * @brief 内部函数:I2C写入数据(调用OpenHarmony HAL层接口)
 /
static unsigned int AHT20_I2C_Write(uint8_t
buffer, uint32_t buffLen) {
    if (buffer == NULL || buffLen == 0) {
        return IOT_FAILURE;
    }
    // 调用HAL层I2C写函数
    return IoTI2cWrite(AHT20_I2C_IDX, AHT20_WRITE_ADDR, buffer, buffLen);
}

https://i-blog.csdnimg.cn/direct/37c5a74323f9445d8cb23412ed119f6f.png

第一个最底层BUILD.gn:


import("//build/lite/config/component/lite_component.gni")

lite_component("iothardware") {

features = [

    ":aht20",  #

]

}



static_library("aht20") {

sources = [

      "aht20.c", 

]



include_dirs = [

    "//utils/native/lite/include",

    "//kernel/liteos_m/components/cmsis/2.0",

    "//base/iot_hardware/interfaces/kits/wifiiot_lite",

    "//base/iot_hardware/peripheral/interfaces/kits",

]

}

在 ~/openharmony3/1.1.3/applications/sample/wifi-iot/app下 新建目录:aht20_test

目录下放2个文件: aht20_test.c 与BUILD.gn。 这里 aht20_test.c 就是根据厂家文档的 test 目录下的那个.c文件,进行的修改:

aht20_test.c 与BUILD.gn

https://i-blog.csdnimg.cn/direct/7d47b08bb4f44da69d777907fe321a2a.png

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 <stdio.h>

#include <unistd.h>



// OpenHarmony系统头文件(使用HAL层接口替代海思私有头文件)

#include "ohos_init.h"

#include "cmsis_os2.h"

#include "hi_gpio.h"

#include "hi_io.h"

#include "iot_i2c.h"   // HAL层I2C接口头文件

#include "iot_errno.h" // HAL层错误码定义



// 任务函数:循环采集温湿度

void Aht20TestTask(void* arg) {

    (void)arg;  // 消除未使用参数警告

    unsigned int retval = 0;  // 错误码类型统一为unsigned int(匹配HAL层)

    float temp = 0.0f, humi = 0.0f;



    // 步骤1:配置GPIO13/GPIO14为I2C0功能(Hi3861默认I2C0引脚)

    hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA);  // SDA引脚

    hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL);  // SCL引脚



    // 步骤2:初始化I2C0(使用HAL层接口,波特率400kHz)

    retval = IoTI2cInit(0, 400 * 1000);  // 替换为HAL层初始化函数

    if (retval != IOT_SUCCESS) {  // 使用HAL层错误码(IOT_SUCCESS)

        printf("I2C0 init failed, err: %u\n", retval);

        return;

    }



    // 步骤3:初始化AHT20传感器

    retval = AHT20_Init();

    if (retval != IOT_SUCCESS) {  // 与驱动中错误码统一

        printf("AHT20 init failed, err: %u\n", retval);

        return;

    }

    printf("AHT20 init success!\n");



    // 步骤4:循环采集并打印数据(1秒/次)

    while (1) {

        retval = AHT20_GetMeasureResult(&temp, &humi);

        if (retval == IOT_SUCCESS) {

            printf("AHT20: Temp = %.2f℃, Humi = %.2f%%RH\n", temp, humi);

        } else {

            printf("AHT20 read failed, err: %u\n", retval);

        }

        sleep(1);  // 延时1秒

    }

}



// 任务创建函数:注册为OpenHarmony启动项

void Aht20Test(void) {

    osThreadAttr_t taskAttr;  // CMSIS-OS2任务属性结构体



    // 配置任务属性

    taskAttr.name = "Aht20TestTask";    // 任务名称

    taskAttr.attr_bits = 0U;            // 任务属性(默认0)

    taskAttr.cb_mem = NULL;             // 回调函数内存(无)

    taskAttr.cb_size = 0U;              // 回调函数内存大小(无)

    taskAttr.stack_mem = NULL;          // 任务栈内存(使用系统分配)

    taskAttr.stack_size = 4096;         // 任务栈大小(4KB)

    taskAttr.priority = osPriorityNormal;  // 任务优先级(正常)



    // 创建任务

    if (osThreadNew(Aht20TestTask, NULL, &taskAttr) == NULL) {

        printf("Create Aht20TestTask failed!\n");

    }

}



// 注册任务:系统启动时自动执行Aht20Test

APP_FEATURE_INIT(Aht20Test);

BUILD.gn:

https://i-blog.csdnimg.cn/direct/3fa191245ebd48239c905212fa351f45.png




static_library("aht20_test") {

    sources = [

        "aht20_test.c",

    ]



    include_dirs = [

        "/home/dragon/openharmony/1.1.3/applications/sample/wifi-iot/app/iothardware",

        "//utils/native/lite/include",

        "//kernel/liteos_m/kal",

        "//base/iot_hardware/peripheral/interfaces/kits",

    ]

deps = [

    "/home/dragon/openharmony/1.1.3/applications/sample/wifi-iot/app/iothardware:aht20",

]

}

第5步:修改app 下的 BUILD.gn

https://i-blog.csdnimg.cn/direct/05a969f4030f4cccbe3f05499a082b4c.png




import("//build/lite/config/component/lite_component.gni")



lite_component("app") {

    features = [

        "aht20_test:aht20_test",

    ]

}