锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

HI3861学习笔记(15)——I2C接口使用

时间:2023-01-10 03:00:00 集成电路hi1cxd9698r集成电路

一、简介

1.1 I2C

I2C(Inter-Integrated Circuit ,内部集成电路) 飞利浦是一种总线 Philip 公司开发的串行总线。它是由一条数据线串行的两条总线(SDA)和一根 时钟线(SDL)组成。两条线都需要上拉电阻。I2C 多个可以在总线上连接 I2C 每个设备都有一个唯一的地址识别。同时只有一个主设备,另一个是从设备。通常 MCU 外设作为主设备控制的设备。

1.2 GPIO复用功能

HI3861V100 芯片有 15 个 GPIO,引脚分布如下:


其中 I2C 设备有 2 个,其中 GPIO 可复用成 I2C 设备如下:

Pin 管脚名称 复用信号
2 GPIO_00 I2C1_SDA
3 GPIO_01 I2C1_SCL
5 GPIO_03 I2C1_SDA
6 GPIO_04 I2C1_SCL
27 GPIO_09 I2C0_SCL
28 GPIO_10 I2C0_SDA
31 GPIO_13 I2C0_SDA
32 GPIO_14 I2C0_SCL

二、API说明

以下 GPIO 接口位于 base\iot_hardware\interfaces\kits\wifiiot_lite\wifiiot_gpio.h

2.1 GpioInit

功能 初始化GPIO外设
函数定义 unsigned int GpioInit(void)
参数
返回 错误码

以下扩展 GPIO 接口位于 base\iot_hardware\interfaces\kits\wifiiot_lite\wifiiot_gpio_ex.h

2.2 IoSetFunc

功能 设置GPIO引脚功能
函数定义 unsigned int IoSetFunc(WifiIotIoName id, unsigned char val)
参数 id:表示GPIO引脚号
val:表示IO复用功能
返回 错误码

以下 I2C 接口位于 base\iot_hardware\interfaces\kits\wifiiot_lite\wifiiot_i2c.h

业务BUILD.gn中包含路径

include_dirs = [         "//utils/native/lite/include",         "//kernel/liteos_m/components/cmsis/2.0",         "//base/iot_hardware/interfaces/kits/wifiiot_lite",     ] 

2.3 I2cInit

功能 初始化指定频率I2C设备
函数定义 unsigned int I2cInit(WifiIotI2cIdx id, unsigned int baudrate)
参数 id:I2C设备ID
baudrate:I2C频率
返回 错误码

2.4 I2cWrite

功能 将数据写入I2C设备
函数定义 unsigned int I2cWrite(WifiIotI2cIdx id, unsigned short deviceAddr, const WifiIotI2cData *i2cData)
参数 id:I2C设备ID
deviceAddr:I2C设备地址
i2cData:表示写入的数据
返回 错误码

2.5 I2cRead

功能 从I2C设备读取数据。读取的数据将保存到i2cData指定的地址
函数定义 unsigned int I2cRead(WifiIotI2cIdx id, unsigned short deviceAddr, const WifiIotI2cData *i2cData)
参数 id:I2C设备ID
deviceAddr:I2C设备地址
i2cData:指的是要读取的数据
返回 错误码

以下扩展 I2C 接口位于 base\iot_hardware\interfaces\kits\wifiiot_lite\wifiiot_i2c_ex.h

2.6 I2cSetBaurate

功能 为I2C设备设置频率
函数定义 unsigned int I2cSetBaudrate(WifiIotI2cIdx id, unsigned int baudrate)
参数 id:I2C设备ID
baudrate:I2C频率
返回 错误码

三、作为主机与BH1750光照强度传感器通信

编译时在业务BUILD.gn中包含路径

include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//base/iot_hardware/interfaces/kits/wifiiot_lite",
    ]

BH1750芯片使用的是I2C协议,I2C_SCL与GPIO_0相连接,I2C_SDA与GPIO_1相连接,所以需要编写软件使用GPIO_0和GPIO_1产生I2C信号去控制BH1750芯片

#include 
#include 
#include 

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_errno.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_i2c.h"
#include "wifiiot_i2c_ex.h"

#define I2C_TASK_STACK_SIZE 1024 * 8
#define I2C_TASK_PRIO 25

#define WRITE_BIT 0x00
#define READ_BIT 0x01

#define BH1750_SLAVE_ADDR 0x23 // 从机地址
#define BH1750_PWR_DOWN 0x00 // 关闭模块
#define BH1750_PWR_ON 0x01 // 打开模块等待测量指令
#define BH1750_RST 0x07 // 重置数据寄存器值在PowerOn模式下有效
#define BH1750_CON_H 0x10 // 连续高分辨率模式,1lx,120ms
#define BH1750_CON_H2 0x11 // 连续高分辨率模式,0.5lx,120ms
#define BH1750_CON_L 0x13 // 连续低分辨率模式,4lx,16ms
#define BH1750_ONE_H 0x20 // 一次高分辨率模式,1lx,120ms,测量后模块转到PowerDown模式
#define BH1750_ONE_H2 0x21 // 一次高分辨率模式,0.5lx,120ms,测量后模块转到PowerDown模式
#define BH1750_ONE_L 0x23 // 一次低分辨率模式,4lx,16ms,测量后模块转到PowerDown模式

/** @brief I2C写数据函数 @param slaveAddr -[in] 从设备地址 @param regAddr -[in] 寄存器地址 @param pData -[in] 写入数据 @param dataLen -[in] 写入数据长度 @return 错误码 */
int I2C_WriteData(uint8_t slaveAddr, uint8_t regAddr, uint8_t *pData, uint16_t dataLen)
{ 
        
    int ret;
    WifiIotI2cData i2c_data = { 
        0};

    if(0 != regAddr)
    { 
        
        i2c_data.sendBuf = &regAddr;
        i2c_data.sendLen = 1;
        ret = I2cWrite(WIFI_IOT_I2C_IDX_1, (slaveAddr << 1) | WRITE_BIT, &i2c_data);
        if(ret != 0)
        { 
        
            printf("===== Error: I2C write status1 = 0x%x! =====\r\n", ret);
            return 0;
        }
    }

    i2c_data.sendBuf = pData;
    i2c_data.sendLen = dataLen;
    ret = I2cWrite(WIFI_IOT_I2C_IDX_1, (slaveAddr << 1) | WRITE_BIT, &i2c_data);
    if(ret != 0)
    { 
        
        printf("===== Error: I2C write status1 = 0x%x! =====\r\n", ret);
        return 0;
    }

    return 1;
}

/** @brief I2C读数据函数 @param slaveAddr -[in] 从设备地址 @param regAddr -[in] 寄存器地址 @param pData -[in] 读出数据 @param dataLen -[in] 读出数据长度 @return 错误码 */
int I2C_ReadData(uint8_t slaveAddr, uint8_t regAddr, uint8_t *pData, uint16_t dataLen)
{ 
        
    int ret;
    WifiIotI2cData i2c_data = { 
        0};

    if(0 != regAddr)
    { 
        
        i2c_data.sendBuf = &regAddr;
        i2c_data.sendLen = 1;
        ret = I2cWrite(WIFI_IOT_I2C_IDX_1, (slaveAddr << 1) | WRITE_BIT, &i2c_data);
        if(ret != 0)
        { 
        
            printf("===== Error: I2C write status = 0x%x! =====\r\n", ret);
            return 0;
        }
    }

    i2c_data.receiveBuf = pData;
    i2c_data.receiveLen = dataLen;
    ret = I2cRead(WIFI_IOT_I2C_IDX_1, (slaveAddr << 1) | READ_BIT, &i2c_data);
    if(ret != 0)
    { 
        
        printf("===== Error: I2C read status = 0x%x! =====\r\n", ret);
        return 0;
    }

    return 1;
}

static void I2CTask(void)
{ 
        
    int ret;
    uint8_t sensor_data[2] = { 
        0};
    uint8_t sensor_data_h, sensor_data_l;
    int cnt = 0;
    uint8_t data;

    GpioInit();

    //GPIO_0复用为I2C1_SDA
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA);

    //GPIO_1复用为I2C1_SCL
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL);

    //baudrate: 400kbps
    I2cInit(WIFI_IOT_I2C_IDX_1, 400000);

    I2cSetBaudrate(WIFI_IOT_I2C_IDX_1, 400000);

    printf("I2C Test Start\n");

    while (1)
    { 
        
        printf("test cnt: %d", cnt++);
        data = BH1750_PWR_ON;              // 发送启动命令
        I2C_WriteData(BH1750_SLAVE_ADDR, 0, &data, 1);
        data = BH1750_ONE_L;               // 设置一次低分辨率模式,测量后模块转到PowerDown模式
        I2C_WriteData(BH1750_SLAVE_ADDR, 0, &data, 1);
        usleep(30000);                     // 设置完成后要有一段延迟
        ret = I2C_ReadData(BH1750_SLAVE_ADDR, 0, sensor_data, 2);
        sensor_data_h = sensor_data[0];
        sensor_data_l = sensor_data[1];
        if(ret == 0) 
        { 
        
            printf("I2C Error");
        } 
        else if(ret == 1)
        { 
        
            printf("*******************\n");
            printf("MASTER READ SENSOR( BH1750 )\n");
            printf("*******************\n");
            printf("data_h: %02x\n", sensor_data_h);
            printf("data_l: %02x\n", sensor_data_l);
            printf("sensor val: %.02f [Lux]\n", (sensor_data_h << 8 | sensor_data_l) / 1.2);
        }

        usleep(1000000);
    }
}

static void I2CExampleEntry(void)
{ 
        
    osThreadAttr_t attr;

    attr.name = "I2CTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = I2C_TASK_STACK_SIZE;
    attr.priority = I2C_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)I2CTask, NULL, &attr) == NULL)
    { 
        
        printf("Falied to create I2CTask!\n");
    }
}

APP_FEATURE_INIT(I2CExampleEntry);

查看打印:


• 由 Leung 写于 2021 年 10 月 10 日

• 参考:【鸿蒙2.0设备开发教程】小熊派HarmonyOS 鸿蒙·季 开发教程
    BearPi-HM_Nano
开发板传感器驱动开发——E53_SC1读取光照强度

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章