一、简介
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 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
#define BH1750_CON_H 0x10
#define BH1750_CON_H2 0x11
#define BH1750_CON_L 0x13
#define BH1750_ONE_H 0x20
#define BH1750_ONE_H2 0x21
#define BH1750_ONE_L 0x23
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 = ®Addr;
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;
}
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 = ®Addr;
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();
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA);
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL);
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;
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读取光照强度
|