Air724UG连接AT24C02实例和避坑--I2C那点事

本文作者分享了在使用Air724UG模块时遇到的挑战,如缺乏官方示例和I2C通信问题。作者详细介绍了如何通过I2C与AT24C02EEPROM交互,包括设置、读写操作和注意事项,以及为何选择外部EEPROM而非内部NVM的考虑。
摘要由CSDN通过智能技术生成

本文适合有使用Air724UG模块基础的读者。

【啰嗦2句】

      近期在试用合宙Air724UG模块,这个模块几年前就在用了,一直用的是AT,也知道片内系统LuatOS其实挺好用,但是一直没有应用场景,我的看法是这个品牌做的文档还是挺全面,只是细节仍然还不够。

      这2天需要用I2C连接一片AT24C02的EEPROM,才发现官方竟然没用示例,并且全网都搜不到?不得已,只能自己研究,才发现官方资料估计也是哪几位大神随便写写,走了不少弯路才成功读写。

【硬件简介】

     熟悉AT24C02的读者可跳过。

     AT24C02是一颗EEPROM芯片,内部包含256Byte的存储空间,通过I2C两线制进行通信读写。

    用的是A14版开发板(卖太贵了!),板上已经扩展4Pin的接口方便直接飞线接24C02,看我的实物图:

     注意:724模块的IO电平大多数是1.8V,而不是熟悉的3.3V哦!

     这里有个惊喜:官方开发板已经把3.3V电平做了转换,可以说非常方便,我刚开始直接就用这4个脚就够了,但是我后来发现其实生产时可以省掉这个电平转换电路,因为我发现AT24C02的手册写着电压范围1.8-5.5V,所以我又特意飞线到1.8V的引脚上,果然读写自如。又可以在批量时省下一笔成本。如果我帮您省了,请记得给我点赞。不过仍需注意:手册也写了当1.8V时,读写的速度是变慢的,请务必根据实际业务需要选择省还是不省,莫怪我没提醒。

【想象中的用法】

      官方例程一:下载官方例程:Luat社区

       解压后在其中\demo\i2c文件下有相应例程,这个例程是介绍Air724UG连接SSD1306主控LCD的,这个主控没接触过,应该是低分辨率的吧估计,暂时不去研究。但是可以通过相应demo了解到如何使用I2C。

      官方例程二:在Luat社区直接搜索I2C,也可以看到一个连接SHT30温湿度传感器的例程。

页面地址:Luat社区

【I2C函数讲解】   

     函数还真没几个,看上去有6个,实际应该是4个:

i2c.setup( id, speed [,slaveaddr] [,isbaud] [,reg16bit])
i2c.write( id, reg, data )
i2c.read( id, reg, num )
i2c.send( id,slave, data )
i2c.recv( id, slave,size )
i2c.close( id )

为什么说是4个呢?首先setup和close就没什么难理解的,无非就是打开和关闭,等同于单片机时序里面的Start和ACK和NAK等等自动完成,这里面最让人莫名其妙的是send\rev其实跟write\read是同效果的才对,只是传递的参数有些差别。那为什么不能压缩成4个,害得我每一个都去研究,也不知道读写成功与否,走了弯路。

直接上代码:

--- 外部Flash,记录开关状态
-- @author CZY Application Team
-- @copyright CZY
-- @release 2024-03-24
module(..., package.seeall)


-- i2cid 1,2,3对应硬件的I2C1,I2C2,I2C3
local i2c_id = 2
--器件地址,根据24C02手册写是A0,读是A1,但是由于Air724要求7bit地址,所以在setup时务必右移1位
--根据Air724示例讲(但是官方教程未见到),执行write或send时,默认是左移1位,并上读写标记0或1
--例如读: (i2c_addr<<1)|0x01,例如写(i2c_addr<<1)|0x00
--最终得到的命令字节其实就是24C02的读写命令字节
local i2c_addr = 0xA0     
-- 读取EEPROM
--addr:存储的位置地址,0开始
function AT24CXX_ReadOneByte(addr)
    if i2c.setup(i2c_id, i2c.SLOW, bit.rshift(i2c_addr, 1)) ~= i2c.SLOW then
        i2c.close(i2c_id)
        log.warn("24C02", "open i2c error.")
        return
    end
    --接收数据
    local RevData = i2c.read(i2c_id, addr, 1)
    i2c.close(i2c_id)
    print("接收的数据:"..addr,string.toHex(RevData))
end
-- 写入EEPROM
--addr:存储的位置地址,0开始
--dat:写入的字节
function AT24CXX_WriteOneByte(addr,dat)
    if i2c.setup(i2c_id, i2c.SLOW, bit.rshift(i2c_addr,1)) ~= i2c.SLOW then
        i2c.close(i2c_id)
        log.warn("24C02", "open i2c error.")
        return
    end
    --写入数据
    i2c.write(i2c_id,addr,dat)
    --等同于下面的命令
    --i2c.send(i2c_id,bit.rshift(i2c_addr,1),{addr,dat})
    i2c.close(i2c_id)
    print("写入的数据:"..addr,dat)
end


sys.taskInit(                                      --起一个协程
    function()
        sys.wait(5000)                          --将协程挂起五秒,此函数只能在协程内使用
        AT24CXX_WriteOneByte(0,0x30)
        sys.wait(5)                             --坑啊,这里写周期要5ms,否则可能有些写入尚未完成不生效,如果批量写入会快些
        AT24CXX_WriteOneByte(1,0x31)
        sys.wait(5)                             --坑啊,这里写周期要5ms,否则可能有些写入尚未完成不生效,如果批量写入会快些
        AT24CXX_WriteOneByte(2,0x32)
        sys.wait(5)                             --坑啊,这里写周期要5ms,否则可能有些写入尚未完成不生效,如果批量写入会快些
        AT24CXX_WriteOneByte(3,0x33)
    end
) 
sys.timerLoopStart(function ()
    AT24CXX_ReadOneByte(0)
    AT24CXX_ReadOneByte(1)
    AT24CXX_ReadOneByte(2)
    AT24CXX_ReadOneByte(3)
end, 3000)

【避坑】

      1、这里最最最大的坑其实就是地址,官方手册没有提到地址是7bit,要求右移,所以一开始我一直用AT24C02手册里面的A0、A1分别写和读,始终得不到结果,好在吃完几个饺子看了一部电影后重新审查示例才发现官方SSD1306的注释里面写了7bit和I2C驱动会默认读写时左移的内容,才从坑里面爬出来。具体注释我已经写在上面的代码了。总结就是24C02的0xA0要先右移1位成为0x50,然后I2C的驱动会在读写时,自动左移并补0和1(写和读),其他信号时序都是驱动完成。

      2、要注意控制每一个周期的时间间隔,手册写的是最大5ms,如果是连续写入则一个循环内没用时间限制,不同循环则尽量延时。

【扩展探讨】

     可能有人会说,724内部有nvm,可以直接写入内部文件系统,为什么要额外用EEPOM存储呢?我试过nvm,效果很好,操作很简单,存储配置没有问题。问题就在我的应用场景是较为频繁写入操作,由于724内部用的是NorFlash,寿命每页一般是10万次,如果按“尽可能递增写入”算法把几十K的空间重复循环利用可能可以到100万次,但是程序的复杂度又高出不少,可靠性根据经验----总有些不按我想象的那样运行的情况,万一因为读写冲突导致程序跑飞,得不偿失啊,debug未必能复现这种随机的问题。另外flash如果更新或重新烧录,有概率会破坏现有数据,所以选择了EEPROM,一般有100万次写入,也都够了,操作好就好在能单字节操作,不用按页操作,用一点点成本换取稳定性和便捷性,可以接受。

原创不易,转载请注明本博客。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值