I2C操作

[!Note]

1.目前仅SV50P系列模组支持该功能。

2.使用前,需要在模组配置中使能 TWI 功能,用生成的新系统包升级,才能正常使用。

3.更多有关模组的使用教程

引入头文件

  #include "utils/I2CHelper.h"

具体操作

  #include "utils/I2CHelper.h"

  #define CFG_L        0x47
  #define CFG_H        0x80
  #define VER_L        0x41
  #define VER_H        0x81

  static void testI2C() {
    uint8_t tx[512], rx[512];
    memset(tx, 0, 512);
    memset(rx, 0, 512);

    /**
     * 定义变量
     *
     * 参数1: i2c总线号
     * 参数2: 从机地址, 一定要注意是 7bit地址
     * 参数3: 超时时间,单位: ms
     * 参数4: 重试次数
     */
    I2CHelper i2c(0, 0x5e, 1000, 5);

    tx[0] = CFG_H;
    tx[1] = CFG_L;

    /**
     * 单工写
     *
     * 参数1: 写数据地址
     * 参数2: 数据长度
     */
    if (!i2c.write(tx, 2)) {
        LOGD("i2c tx cfg error!\n");
    }

    /**
     * 单工读
     *
     * 参数1: 读数据地址
     * 参数2: 数据长度
     */
    if (!i2c.read(rx, 1)) {
        LOGD("i2c rx cfg error!\n");
    }

    LOGD("i2c reg[0x%x%x]=%x\n", CFG_H, CFG_L, rx[0]);
    memset(rx, 0, 512);

    /**
     * 半双工传输,即共用读写,中间无stop信号
     *
     * 参数1: 写数据地址
     * 参数2: 写数据长度
     * 参数3: 读数据地址
     * 参数4: 读数据长度
     */
    if (!i2c.transfer(tx, 2, rx, 1)) {
        LOGD("i2c i2c_transfer cfg error!\n");
    }

    LOGD("i2c reg[0x%x%x]=%x\n", CFG_H, CFG_L, rx[0]);

    tx[0] = VER_H;
    tx[1] = VER_L;
    if (!i2c.write(tx, 2)) {
        LOGD("i2c tx ver error!\n");
    }

    if (!i2c.read(rx, 1)) {
        LOGD("i2c rx ver error!\n");
    }

    LOGD("i2c reg[0x%x%x]=%x\n", VER_H, VER_L, rx[0]);
    memset(rx, 0, 512);
    if (!i2c.transfer(tx, 2, rx, 1)) {
        LOGD("twi i2c_transfer ver error!\n");
    }

    LOGD("i2c reg[0x%x%x]=%x\n", VER_H, VER_L, rx[0]);
  }

其他接口操作请参见头文件注释说明。

I2C操作—EEPROM读写案例

以AD24C32存储器为例,我们主要关注器件地址即从机地址和设备的电气特性。

AD24C32

//实例一个I2C对象,参数2从机地址为7bit地址,由上图3和图10可知器件地址为1010 000R/W,最低位为读写位,读写位底层会根据调用的方法read/write来决定,此地址右移一位的结果为0101 0000即0x50
static I2CHelper i2c(1, 0x50, 1000, 5);

read

write

Applianceproperty

/**
 * 读操作
 * I2C对象在构造时已经传入器件地址,在调用read/write方法时器件地址会自动拼接
 * 参数1:字地址,即读数据的起始地址
 * 参数2:存放读出数据的容器
 * 参数3:读数据的长度
 */
int i2c_readReg(unsigned short reg_addr, unsigned char *buf, int len)
{
    int res = 0;
    //由图14可知,读数据之前需要先写字地址,即告诉芯片要从什么位置开始读数据
    unsigned char buff[2];
    buff[0] = (reg_addr >> 8);
    buff[1] = reg_addr;
    //写2个字节的字地址
    i2c.write(buff, 2);
    usleep(2*1000);
    res = i2c.read(buf,len);
    return res;
}

/**
 * 页写操作
 * 参数1:字地址,即读数据的起始地址
 * 参数2:待写入的数据
 * 参数3:待写入的数据的长度
 */
int i2c_writeReg(unsigned short reg_addr, unsigned char *buf, int len)
{
    int res = 0,i;
    unsigned char *buff = 0;
    buff = (unsigned char *)malloc((len+2));
    //由图12可知,写数据时需要数据帧需要带字地址,即告诉芯片要从什么位置开始写数据
    buff[0] = (reg_addr >> 8);
    buff[1] = reg_addr;
    //由图12可知,字地址之后紧接是待写入的数据内容
    for(i = 0; i < len; i++)
        buff[(i+2)] = buf[i];
    res = i2c.write(buff, (len+2));
    free(buff);
    return res;
}

/**
 * 测试代码
 * 测试代码先写入数据,然后再读取数据,对比写入和读出的数据内容
 */
void I2C_Test_EEPROM(){
    char wbuf[32] = {0};
    memset(wbuf,0,32);
    strcpy(wbuf,"www.zkswe.com");
    LOGD("\n");
    if(i2c_writeReg(0,(unsigned char*)wbuf,strlen("www.zkswe.com"))){
        LOGD("write \"%s\" success!",wbuf);
    }
    //由电器特性可知,写周期时间为2-5ms,在下面读之前有写的操作,所以这里需要延时一定的时间
    usleep(5*1000);
    unsigned char rbuf[32] = {0};
    memset(rbuf,0,32);
    if(i2c_readReg(0,rbuf,32)){
        LOGD("read content:");
        for(unsigned int j= 0;j<strlen("www.zkswe.com");j++){
            LOGD("%d:%c\n",j,rbuf[j]);
        }
    }else{
        LOGD("Read FAIL");
    }
    LOGD("\n");
}

/**
 * 日志
 * 由日志可知,读出的数据和写入的数据比较无误。
 * 综上,I2C操作主要看从设备的通信协议,还需要关注从设备的电器特性,否则通讯可能会出现异常。
 */
D/zkgui   (  917):
D/zkgui   (  917): write "www.zkswe.com" success!
D/zkgui   (  917): read content:
D/zkgui   (  917): 0:w
D/zkgui   (  917): 1:w
D/zkgui   (  917): 2:w
D/zkgui   (  917): 3:.
D/zkgui   (  917): 4:z
D/zkgui   (  917): 5:k
D/zkgui   (  917): 6:s
D/zkgui   (  917): 7:w
D/zkgui   (  917): 8:e
D/zkgui   (  917): 9:.
D/zkgui   (  917): 10:c
D/zkgui   (  917): 11:o
D/zkgui   (  917): 12:m
D/zkgui   (  917):
powered by Gitbooklast modified: 2023-08-03 16:20:01

results matching ""

    No results matching ""