本实践目标
- 了解I2C的基本概念以及应用方式
- 熟悉air20x的I2C API
- 在使用具体的I2C器件之前,我们首先需要确认的I2C的外设地址,这个除了查文档,利用电路判断之外,我们可以尝试一个“扫描发现”的方式
- 为下一批实践,驱动I2C的0.96 oled,4通道16bit ADS1115的使用,带闹钟时钟PCF8563的控制
- 试试上I2C是一类总线,以上外设可以同时接入,我们下一批实践也可尝试同时接入设备的通讯协调
相关资料
- 《air202_硬件设计手册_v1.x》
- 《Luat 脚本开发指南V2.x》
- 《lua扩展库V1.x》
- I2C协议wikipage
- I2C总线特性V2.1
模块连接
AIR202 I2C接口
管脚名 | 管脚号 | I/O |
---|---|---|
I2C_CLK | 29 | O |
I2C_SDA | 30 | IO |
供电
管脚名 | 管脚号 | I/O |
---|---|---|
VDDIO | 24 | O |
****I2C总线需要接电阻上拉,电平标准最好与VDDIO保持一致**
I2C外设的连接示意
image**** 此处使用的是air202的S5系统扳,虽然比较起来S6更简约经济,但是从快速实验的角度,S5可以节约很多的时候,我们基本上只需要一个android手机的micro USB线缆就可以开始了**
要点分析及其说明
-
固件
请使用最新版本的固件:Luat_VXXXX_Air202.lod
-
I2C硬件id
air202的I2C硬件ID为0,在做实验的时候验证为0
**** 此处可能存在一些小的偏差,官方的demo中i2cid=2, 硬件文档的描述也未I2C3SDA/I2C3SCL**
也许此处I2C3是针对8955的硬件特性暴露的顺序,而对于air202的luat固件,它的顺序为0 -
I2C 时序示意
image
此处信息并非我们开启I2C实践的必要条件,但是可以更满足我们的好奇心:)
图片来自维基百科
其中:- S 开始位 start bit
- B1-BN 数据位 data bit
- P 停止位 stop bit
-
I2C API
打开i2c接口
speed = i2c.setup( id, speed, slave )往指定的寄存器地址 reg 传输数据
wrote = i2c.write( id, reg, data )读取指定寄存器地址 reg 的数据内容
data = i2c.read( id, reg, num )关闭 I2C 接口
speed = i2c.close( id )I2C文档地址,I2C为luat core支持,无需require lib中的组件
-
I2C 外设地址的验证
speed = i2c.setup( id, speed, slave )
打开I2C接口的API可以给我们一个反馈,但这个反馈是针对I2C接口本身的创建,而非外设地址是否有效。
外设地址对于我们操作目标的IC或模块是必要条件,而一般情况下这个地址由两个要素决定:
芯片特性 + 外部电路的地址设定
此处我们暂且假设外部电路的地址设定都保持了芯片的默认特性例如 ads1115的地址为0x48, 时钟IC pcf8563的地址为0x51, 0.96 oled的地址为0x3c
这些地址,我们如何可以有效便捷的定位到呢? 最精确的方式应该是从datasheet中获取,也许是个人作为硬件新手, 经验有限的缘故,当初在这个部分的确花费了不少时间,也遇见了不少困惑,经过几个I2C设备的实践,得到一些浅显的经验,抛砖引玉一下:
- i2c.setup API的形式只能检验air20x模块的I2C特性是否正常,无法校验外部地址
- i2c 的地址范围为0x00 - 0x7f
- 一般的I2C外设,寄存器0“大多数情况下”应该是可读取的,我们可以将其作为“验证地址”, 如果遇见目标外设的确不可用寄存器0,那我们就切换一个地址去验证好了:)
- 在这个思路下,如果我们对寄存器0,进行外设地址0x00 - 0x7f的循环读写尝试,得到有效回应,则可定位该地址
- 相对写操作尝试,读操作更是“无侵害”的尝试
-
在此思路下的代码实现
-
经过实际操作,的确可以得到实际接入的设备地址
i2cscan : located live I2C asset on the bus : 0x48
i2cscan : located live I2C asset on the bus : 0x51
代码地址
https://github.com/wingpengfei/luatcookie/tree/master/air20x/src/i2c
网友评论