模块支持一个硬件 I2C 接口。只能用 PINNAME_I2C_SCL 作为 SCL, PINNAME_I2C_SDA 作 为 SDA 如果要使用其它引脚,则只能使用模拟 I2C 接口, 开发者可自行在 APP 中添加,或者联系我司提供。 本文介绍的数据结构和 API 可以参考 SDK 中 Zyf_I2C.h 文件。
I2C 函数使用步骤如下: Step 1:初始化 I2C 接口。调用 ZYF_I2clnit 函数初始化 I2C 通道,包括特殊 GPIO 引脚和通道号。 Step 2:配置 I2C 接口。调用 ZYF_I2cConfig 函数来配置从机需要的参数。更多信息请参考 API 描述。 Step 3:读取数据。调用 ZYF_I2cReadBytes 函数从特定的从机读取数据。 Step 4:发送数据。调用 ZYF_I2cWriteBytes 函数给特定的从机发送数据。
1.3.1 ZYF_I2cInit 初始化 I2C函数原型 int32_t ZYF_I2cInit(uint32_t chnnlNo, Enum_PinName pinSCL, Enum_PinName pinSDA, bool I2Ctype)参数 chnnlNo: [输入]I2C 通道 pinSCL: [输入]I2C SCL 引脚 pinSDA: [输入]I2C SDA 引脚 I2Ctype: [输入]I2C 类型,0:模拟;1:硬件;返回结果 ZYF_RET_OK,此函数成功。 ZYFIRETERR_NOSUPPORTPIN,输入引脚无效。 ZYF_RET_ERR_NOSUPPORTMODE,输入引脚没有 I2C 模式 ZYF_RET_ERR_PINALREADYSUBCRIBE,该引脚已在其他位置使用。例如,此引脚已用作 EINT 或 gpio。
1.3.2 ZYF_I2cConfig 置 配置 I2C
函数原型 int32_t ZYF_I2cConfig(uint32_t chnnlNo,uint32_t chnnlNo,uint8_t slaveAddr, uint32_t speed)
参数 chnnlNo: [输入] I2C 通道 slaveAddr: [输入] 从机地址。 speed: [输入] 速度,100Kbps~3.5Mbps返回结果 ZYF_RET_OK,此函数成功。 ZYFIRETERR_I2C_SAME_SLAVE_ADDRESS,已经设置了您要设置的从站地址,或者使用了该地址。 ZYF__RET_ERR_NORIGHTOPERATE,PIN 不在 I2C 模式或未初始化。
1.3.3 ZYF_I2cReadBytes 取 读取 I2C 数据函数原型 int32_t ZYF_I2cReadBytes(uint32_t chnnlNo,uint32_t chnnlNo,uint8_t RegAddr, uint8_t *pBuffer, uint16_t len)参数 chnnlNo:[输入] I2C 通道 RegAddr:[输入] 寄存器地址 pBuffer:[输出] 从指定寄存器读取到的数据 len:[输入] 读取数据长度。1 <= len <= 8。I2C 控制器每次最多传输支持 8 字节返回结果 如果没有错误,则返回读取数据的长度。 ZYF_RET_ERR_PARAM,参数错误。 ZYF__RET_ERR_I2CHWFAILED,也许硬件有问题。 ZYF_RET_ERR_NORIGHTOPERATE,PIN 不在 I2C 模式或未初始化。 ZYF_RET_ERR I2C_SLAVE NOT_FOUND,找不到指定的从站。
1.3.4 ZYF_I2cWriteBytes 写 写 I2C 数据
函数原型 int32_t ZYF_I2cWriteBytes(uint32_t chnnlNo,uint32_t chnnlNo,uint8_t RegAddr, uint8_t *pData, uint16_t len)参数 chnnlNo:[输入] I2C 通道 RegAddr:[输入] 寄存器地址 pData:[输入] 写入寄存器的数据 len:[输入] 数据长度。1 <= len <= 8。I2C 控制器每次最多传输支持 8 字节返回结果 如果没有错误返回,则为写入数据的长度。ZYF_RET_ERR_PARAM,参数错误。ZYF_RET_ERR_I2CHWFAILED,也许硬件有问题。ZYF_RET_ERR_NORIGHTOPERATE,PIN 不在 I2C 模式或未初始化。ZYF_RET_ERR_I2C_SLAVE_NOT_FOUND,未找到指定的从站。
1.3.5 ZYF_I2cUninit 放 释放 I2C函数原型 int32_t ZYF_I2cUninit(uint32_t chnnlNo)参数 chnnlNo:[输入] I2C 通道返回结果 ZYF_RET_OK 成功 ZYF_RET_ERR_PINALREADYSUBCRIBE 该引脚已在其他位置使用。例如,此引脚已用作 EINT 或 gpio。
本章节主要介绍如何在 SDK 中使用 example_i2c.c 单独测试 I2C 功能。 编译方法:.\examples\build\对应的.bat 文件双击执行或打开就可以编译。 生成文件:.\out\对应目录\hex\M601_example_**.pac
使用 ZYF_I2cInit()初始化 I2C 的通道和引脚等。使用 ZYF_I2cConfig()配置速率相关参数。测试如下:使用 AT24xx_WriteTest()向指定地址写入数据,再使用 AT24xx_ReadTest()读取该指定地址,最后通过 ZYF_I2cUninit()释放此I2C。
#include <stdint.h> #include "zyf_trace.h" #include "zyf_iic.h" #include "zyf_gpio.h" #include "zyf_app.h" #include "zyf_uart.h" #include "zyf_thread.h" #include "OLED_I2C.h" static Uart_Param_t g_uart1param; void UartWriteCallBack(void* Param) // general com { Uart_Param_t *uartparam = (Uart_Param_t *)Param; if(Param == NULL) { return; } ZYF_UartWrite(uartparam->port,(uint8_t *)"UartWrite succeed\r\n",strlen("UartWrite succeed\r\n")); ZYF_UartWriteCallbackSwitch(uartparam->port,false); } void UartReadCallBack(void* Param) // { uint32_t recvlen = 0; Uart_Param_t *uartparam = (Uart_Param_t *)Param; ZYF_LOG("Uart%d recv",uartparam->port); while(ZYF_UartRead(uartparam->port, &(uartparam->uartbuf[recvlen]), 1)) { ZYF_LOG("recv :x",uartparam->uartbuf[recvlen]); recvlen++; } ZYF_UartWrite(uartparam->port,uartparam->uartbuf,recvlen); ZYF_UartWriteCallbackSwitch(uartparam->port,true); } static void AppUartInit(void) { int32_t ret; g_uart1param.port = DEBUG_PORT; ZYF_UartRegister(g_uart1param.port, UartReadCallBack,&g_uart1param); ZYF_UartWriteCbRegister(g_uart1param.port,UartWriteCallBack,&g_uart1param); ZYF_UartOpen(g_uart1param.port, 115200, ZYF_FC_NONE); ZYF_LOG("AppUartInit"); return; } /* void AT24xx_WriteTest(void) { uint8_t data[8] = {0x3A, 0x4B, 0x1C, 0xD6, 0x7F, 0x5E, 0xD9, 0xA4}; uint16_t len; ZYF_LOG("I2C write test ..."); len = ZYF_I2cWriteBytes(ZYF_I2C_1, 0, data, 8); if (8 == len) { ZYF_LOG("I2C write OK !"); } } void AT24xx_ReadTest(void) { uint8_t data[8] = {0}; uint16_t len; ZYF_LOG("I2C read test ..."); len = ZYF_I2cReadBytes(ZYF_I2C_1, 0, data, 8); if (8 == len) { ZYF_LOG("I2C read OK ! => X,X,X,X,X,X,X,X", data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7]); } } void ZYF_AppI2cTest(void *param) { ZYF_I2cInit(ZYF_I2C_1, PINNAME_I2C_SCL, PINNAME_I2C_SDA, ZYF_I2C_TYPE_HW); ZYF_I2cConfig(ZYF_I2C_1, 0xA0 >> 1, ZYF_I2C_BPS_100K); AT24xx_WriteTest(); ZYF_ThreadSleep(500); AT24xx_ReadTest(); ZYF_ThreadSleep(500); ZYF_I2cUninit(ZYF_I2C_1); } */ void IICThread_Example(void * Param) { ZYF_MsgQ_t *ptMsg; ZYF_AppMsg_t tMsg; int iRet = -1; ptMsg = ZYF_MsgQCreate(10, sizeof(ZYF_AppMsg_t)); ZYF_LOG("thread enter!"); // ZYF_AppI2cinit(); OLED_Init(); OLED_Test(); } static void prvInvokeGlobalCtors(void) { extern void (*__init_array_start[])(); extern void (*__init_array_end[])(); size_t count = __init_array_end - __init_array_start; for (size_t i = 0; i < count; ++i) __init_array_start[i](); } int appimg_enter(void *param) { AppUartInit(); ZYF_LOG("application image enter, param 0x%x", param); prvInvokeGlobalCtors(); ZYF_ThreadCreate("IICThread_Example", IICThread_Example, NULL, ZYF_PRIORITY_NORMAL, 4*1024); return 0; } void appimg_exit(void) { OSI_LOGI(0, "application image exit"); }