3. M601 模块 I2C 使用介绍

1 I2C 的使用


1.1 概述


模块支持一个硬件 I2C 接口。只能用 PINNAME_I2C_SCL 作为 SCL,
PINNAME_I2C_SDA 作 为 SDA 如果要使用其它引脚,则只能使用模拟 I2C 接口,
开发者可自行在 APP 中添加,或者联系我司提供。
本文介绍的数据结构和 API 可以参考 SDK 中 Zyf_I2C.h 文件。


1.2 用法


I2C 函数使用步骤如下:
Step 1:初始化 I2C 接口。调用 ZYF_I2clnit 函数初始化 I2C 通道,包括特殊 GPIO 引脚和通道号。
Step 2:配置 I2C 接口。调用 ZYF_I2cConfig 函数来配置从机需要的参数。更多信息请参考 API 描述。
Step 3:读取数据。调用 ZYF_I2cReadBytes 函数从特定的从机读取数据。
Step 4:发送数据。调用 ZYF_I2cWriteBytes 函数给特定的从机发送数据。

1.3 API 函数


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。

2 I2C 例程介绍


本章节主要介绍如何在 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 :%02x",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 ! => %02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X", 
                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");
}


猜你喜欢

转载自blog.csdn.net/w_hizyf_m/article/details/107082992