I2C总线作为常用的通信接口,是一种简单、双向二线制同步串行总线,只需要两根线即可在连接于总线上的器件之间传送信息,属于半双工模式。MN316 OpenCPU支持1路I2C功能,可实现与外部I2C器件(如EEPROM、温湿度传感器等)通信。本文将从使用流程、接口解析、demo代码解析及注意事项四个方面介绍I2C使用方法。
- I2C使用流程解析
图1为使用MN316 OpenCPU I2C功能时的常见流程及相关函数接口介绍。
图 1 I2C功能使用流程图
- I2C功能接口
I2C功能主要包含以下接口,可在cm_i2c.h中查看。
1、I2C模块初始化
图 2 I2C串口初始化接口
使用I2C功能前需要初始化I2C模块。
(1)dev 通路编号,目前仅支持通路1:CM_I2C_DEV_1;
(2)cfg 配置,结构成员包括:
addr_type,设备地址类型,7位寻址和10位寻址,I2C总线规范规定,从机地址为7位长,其次是读/写位。其中0表示写,1表示读,如图3。
图3 从机设备地址
关于设备地址的确认需要参考实际测试的I2C器件datasheet,后文以某EEPROM进行举例说明。
mode,主从模式,目前仅支持主模式;
clk,通信速率,目前仅支持CM_I2C_CLK_100KHZ;CM_I2C_CLK_400KHZ两种速率。需要提前确认I2C器件是否支持以上两种速率。
2、I2C模块去初始化
图4 I2C串口去初始化接口
调用此接口可关闭I2C通道。
3、I2C写接口
图 5 I2C写接口
(1)dev,通路编号,目前仅支持通路1:CM_I2C_DEV_1;
(2)slave_addr,从机设备地址,即外部传感器的设备地址。
以7位寻址举例:如某EEPROM器件datasheet中描述设备地址给出为8位地址1010 000,第7位表示读写位,写地址则为10100000。
图6 从机设备地址
若采用7位寻址,则只需提取该地址的前7位,则为01010000,为0X50。设备地址需要根据外设的datasheet进行确认。
(3)data,待写入的数据,若外设还具有寄存器地址,则需要把寄存器地址当做数据一起传入;
(4)len,待写数据长度,单次最大只支持写入8个字节;
(5)返回值,实际写入长度,可通过此接口判断是否写入成功。
4、I2C读接口
图 7 I2C读接口
(1)dev,通路编号,目前仅支持通路1:CM_I2C_DEV_1;
(2)slave_addr,从机设备地址,也就是外部传感器的设备地址。
(3)data,存放读取数据的缓存buffer,若需要读取外设某寄存器地址上的数据,则需要先使用写接口写入相应的寄存器地址,再进行读取;
(4)len,待写数据长度,单次最大只支持写入8个字节;
(5)返回值,实际写入长度,可通过此接口判断是否写入成功。
- Demo使用方法
在源SDK demo以EEPROM(型号is24c256)为例,写明了一个测试函数。使用测试命令CM:I2C即可测试,实现的是写入并读出1个字节。
1、编译demo测试固件
图 8 I2C demon测试接口
(1)若要使用demo中的测试功能,需使用编译命令build.bat dbrs_h0 demo,其中dbrs需要根据模组型号相应编译;
(2)测试命令:CM:I2C。
2、测试程序逻辑
(1)该测试程序逻辑主要是向外设EEPROM,型号为is24c256,写入一个字节’A’,再进行读取;
图 9 编写外设EEPROM is24c256读写测试接口
(2)可以看到在初始化I2C完成后,向I2C写数据,需要先传入寄存器地址,然后再加上数据,然后一并传入cm_i2c_write写接口,完成写入操作;
图 10 MN316原生接口向外设EEPROM写数据注意事项
(3)可以看到在读取操作时,需要先写入需要读的地址,然后再进行读取。
图 11 MN316原生接口向外设EEPROM读数据事项
3、I2C读写示例
笔者使用EEPROM BL24C256A 256KB为例,设备7位地址为0X50,示例:
图 12 外设EEPROM BL24C256A 初始化
图 13 向外设EEPROM BL24C256A 写数据程序
图 14 外设EEPROM BL24C256A 读数据程序
写好读写接口后,只需要在主函数进行调用即可,1、初始化;2、写数据、3、读数据。
图 15 外设EEPROM BL24C256A 读写test数据程序
测试结果如下图:
图 16 外设EEPROM BL24C256A 读写测试验证
可以看到data[]默认数据为0XFF,通过EEPROM写读后,变为test,说明模组与EEPROM可以通过I2C正常通信。
- 注意事项
1、为什么I2C通信不成功?
(1)检查cm_i2c_open初始化是否成功,注意配置的通信速率100KHZ或400KHZ是否在外设支持的通信范围内;
(2)外设地址是否确认无误,常见采用7位寻址,需要根据外设的数据手册,区分给出的是7位还是8位地址,若是8位地址则需要保留取前7位地址即可;
(3)检查cm_i2c_read/write读写接口,是否实际返回读写成功字节数,若返回错误,检查设备的外设的寄存器地址是否传入有误,数据长度是否一致。
2、I2C如何读取外设某寄存器中的数据?
目前提供的读cm_i2c_read接口,需把寄存器地址通过写接口写入后,再进行读取。