iic指南

1 篇文章 0 订阅

iic接口

简介

Air724UG模块提供3个I2C接口,速率支持FAST(400KHz)、SLOW(100KHz)、3500KHz。外设地址支持0x00-0x7f。其中AT版本并不支持I2C操作,只能在luat二次开发方式使用。3路I2C分别是有由如下管脚复用:


iic接口控制

iic库由底层core实现,相关API接口如下:

iic接口描述
i2c.setup()打开iic
i2c.send()向从设备写数据
i2c.recv()向从设备读取数据
i2c.write()往指定的寄存器地址 reg 传输数据
i2c.read()读取指定寄存器地址 reg 的数据内容

详细的API介绍见luat core API章节

相关硬件接口

接口名称复用管脚作用
I2C1CAMI2C_SCL1I2C1_SCL51I2C1时钟信号
I2C1CAMI2C_SDA1I2C1_SDA50I2C1数据信号
I2C2I2C2_SCLI2C2_SCL32I2C2时钟信号
I2C2I2C2_SDAI2C2_SDA31I2C2数据信号
I2C3ZSP_UART_TXDI2C3_SCL7I2C3数据信号
I2C3SIM0_DETI2C3_SDA8I2C3时钟信号

iic使用示例

这里用一个SHT30温湿度传感器做一个演示,代码如下:
1.定义iic id号,设备地址,单次读取的命令

local i2c_id = 2 -- I2C id号
local i2c_addr = 0x45 -- i2c地址
local TEMP_MEASURE = {0x2C, 0x06} -- 单次读取命令

2.定义一个校验算法的函数

-- CRC8校验算法
-- data : 原始数据按字节table
-- num : 数据(table)长度
-- @return crc值
local function Calc_CRC8(data, num)
    local crc, bits, bytes = 0xFF, 0, 0
    for bytes = 1, num do
        crc = bit.bxor(crc, data[bytes])
        for bits = 8, 1, -1 do
            if (bit.band(crc, 0x80) ~= 0x0) then
                crc = bit.bxor(bit.clear(bit.lshift(crc, 1), 8, 9, 10), 0x31)
            else
                crc = bit.lshift(crc, 1)
            end
        end
    end
    return crc
end

3.定义一个读取传感器函数

-- 读取传感器
function sht30()
    if i2c.setup(i2c_id, i2c.SLOW, i2c_addr) ~= i2c.SLOW then
        i2c.close(i2c_id)
        log.warn("SHT30", "open i2c error.")
        return
    end
  
    i2c.send(i2c_id, i2c_addr, TEMP_MEASURE)
    local RevData = i2c.recv(i2c_id, i2c_addr, 6)
    i2c.close(i2c_id)

    if RevData and #RevData >= 6 then
        log.warn("SHT30", RevData:toHex())
        -- 解包
        local _, t_H, t_L, t_crc, h_H, h_L, h_crc = pack.unpack(RevData, 'b6')
        -- 数据转换得到温湿度
        local rawT, rawR = t_H * 256 or t_L, h_H * 256 or h_L -- 左移为*256
        local temp, humi = -45 + rawT * 175 / 65535,
                           math.ceil(100 * rawR / 65535)
        -- 数据检验(通过返回正确值,否则nil)
        local T_Tbl, R_Tbl = {t_H, t_L}, {h_H, h_L}
        local T_crc, R_crc = Calc_CRC8(T_Tbl, 2), Calc_CRC8(R_Tbl, 2)
        if T_crc ~= t_crc then temp = nil end
        if R_crc ~= h_crc then humi = nil end
        if temp and humi then
            -- body
            -- 四舍五入处理
            temp = string.format("%.01f", temp)
            humi = string.format("%d", humi)

            -- local tempBin = pack.pack(">H", temp * 10)
            -- local humiBin = pack.pack("b", humi)    

            -- 返回
            log.warn("SHT30", "temp =", temp, " humi =", humi)
            return temp, humi
        end
    else
        log.warn("SHT30", "read sensor data fail..")
    end
end

4.启动一个循环定时器,间隔2s读取一次传感器数据

sys.timerLoopStart(sht30, 2000)

5.在了解并修改了DEMO后将demo和对应的底包下载到开发板,下载的方式这里不详细说明请参考环境搭建中的烧录章节。
6. 下载完成后重启开发板,在luatools上可以看到打印的数据:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gRqLWqAS-1624847411455)(http://openluat-luatcommunity.oss-cn-hangzhou.aliyuncs.com/images/20210422163612488_微信截图_20210422163321.png “undefined”)]

常见问题

http://doc.openluat.com/article/2111/0

1、i2c每次读写数据前都需要setup一次吗?

不需要

正常的业务逻辑为:
i2c.setup
…此处可以多次读写数据
i2c.close
setup之后,只要没有close,就可以反复读写数据
一旦执行了close,下次读写数据前,必须再次setup

2、i2c通信时模块可以做从设备吗?

注意:模块I2C只能做主设备,外部需要上拉,在配置FAST速率时,上拉电阻阻值不要大于4.7K。

3、i2c通信时主从机电平不一样,要做电平转换吗?

如果主从设备的参考电平不一致,请注意做电平转换。如下图:

相关资料以及购买链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值