IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> HI3861学习笔记(15)——I2C接口使用 -> 正文阅读

[嵌入式]HI3861学习笔记(15)——I2C接口使用

一、简介

1.1 I2C

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

1.2 GPIO复用功能

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


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

Pin管脚名称复用信号
2GPIO_00I2C1_SDA
3GPIO_01I2C1_SCL
5GPIO_03I2C1_SDA
6GPIO_04I2C1_SCL
27GPIO_09I2C0_SCL
28GPIO_10I2C0_SDA
31GPIO_13I2C0_SDA
32GPIO_14I2C0_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 I2cSetBaudrate

功能为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 <stdio.h>
#include <string.h>
#include <unistd.h>

#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读取光照强度

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-10-11 17:39:56  更:2021-10-11 17:40:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:38:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码