smbus和PCF8591_树莓派_IIC_I2C_smbus的write_byte,write_byte_data,read_byte,都在这里了

关于smbus和PCF8591的一些笔记

b y   57 by \ 57 by 57

其实这个事情,PPT上已经讲的很清楚了,但是还是有必要记一下,因为smbus这个玩意它没文档(或者说是我找不到文档)……

首先, I 2 C I^2C I2C的通信原理什么的就不赘述了,前面的PPT都有,master和slaver,高电平和低电平的各种转换……至少有两个PPT都是讲这个的,也讲得很清楚。

那我下面主要说说smbus里面的一些代码为什么要那么用吧,这些是PPT里没有讲得太清楚的,hmmm,至少我是这么觉得,所以我写一下,也希望能帮到大家。

首先得了解一些 I 2 C I^2C I2C通信的原理和PCF8591通信的原理。

在这里插入图片描述

这张PPT讲述的是为什么器件的地址为0x48。

然后就是控制字格式,上面讲的是在 I 2 C I^2C I2C总线协议中,启动条件之后的第一个字节是发送的器件地址,那么第二个字节发送的就是其控制字,这个将被储存到PCF8591的控制寄存器中。

在这里插入图片描述
嗯哼,PPT上的字比较小,我在这里就手打一遍,这个关系到之后的smbus的用法啊!

  • 最高位默认为0.

  • 第6位是选择是否允许模拟电压输出,在 D → A D\rightarrow A DA的时候设置为1, A → D A\rightarrow D AD的时候设置为0或者1,都可以。

  • 第5和4位是选择模拟电压输出方式的,00表示的是单端输入,我们这里就用00,还有其他的输入见下图(作为补充了解):

    • 其中,Three differential inputs 三差分输入

    • 10:单端差分混合

    • 11:二差分输入

    • 图源网络,侵删。

      在这里插入图片描述

  • 第3位默认为0.

  • 第2位是自动增量使能位,也就是说,如果这一位置为1,那么每一次A/D转换(模数转换)后通道数目将会变化(即增1).

  • 第1位和第0位是AD转换时候选择的,选择的是把哪一个通道输入的电压转换为数字量。

哦吼,到这里我相信你已经可以推测出来咱们PPT的代码里面的smbus里面的那几个比较核心一点的,比如说bus.write_byte(address, 0x40)bus.read_byte(address)bus.write_byte_data(address, 0x40, temp)具体是什么了。

当然,如果你还是不是很清楚,请继续往下看。

I 2 C I^2C I2C协议无非存和取,那么这些函数肯定代表着存取操作。这里先给出来,write表示存,read表示取。或者说这些存取,表示的是往PCF8591里写东西,和从PCF8591里往出读东西。(具体原理看讲 I 2 C I^2C I2C的PPT)

知道了以上,下面开始分析代码。

def setup(Addr):
    global address
    address = Addr

我们看到PCF8591.py的代码,里面首先就是一个setup(),设置了address,这里设置address,可以往后看,后面在调用这个setup()的时候,设置了地址为0x48.这里的0x48的得到,就是通过上面的第一个PPT图里的指示得到的。当然,也可以用sudo i2cdetect -y 1来做,但是知道原理就更牛辣!23333

def read(chn):
    try:
        if chn == 0:
            bus.write_byte(address, 0x40)
        if chn == 1:
            bus.write_byte(address, 0x41)
        if chn == 2:
            bus.write_byte(address, 0x42)
        if chn == 3:
            bus.write_byte(address, 0x43)
        bus.read_byte(address)
    except Exception as e:
        print("Address: %s" % address)
        print(e)
    return bus.read_byte(address)

这里是读东西,从四个不同的通道里读入东西,chn表示选择通道的编号。像write_byte(),这里是上面的第二个PPT图,即给 I 2 C I^2C I2C设备发送一下控制字。0x400x41这些,转换成二进制不就是1000000,1000001吗?再加上最高位默认为0,这不正好就是一个控制字吗?用0x40来看,补上最高位默认的0,就成为了0100 0000,对应一下,就成了:允许模拟电压输出+单端输入+不启动通道的自动增量+AD转换通道设置为0号通道.

然后,bus.write_byte(address,balabala)之后,就开始bus.read_byte(address),就是从address的位置开始读东西了。这就完成了一次 I 2 C I^2C I2C的通信了。读完之后把读到的东西返回一下,这个read函数就结束了(毕竟咱的代码里还有其他地方要用到读入的东西,所以read函数肯定不是只启动一次通信那么简单,还要保存这样那样,比如当这个文件被当作main执行的时候就会有一个print("AIN0 = ",read(0)的操作))。

def write(val):
    try:
        temp = val
        temp = int(temp)
        bus.write_byte_data(address, 0x40, temp)
        
    except Exception as e:
        print("Error: Device address: 0x%4X" % address)
        print(e)

这个里面跟上面有一些不同,在于这个里面是使用的write_byte_data(address, 0x40, temp),跟上面的write_byte()不同。这样理解就好了:write_byte_data(),不仅完成了write_byte()的告诉 I 2 C I^2C I2C设备控制字是什么的指令,还增加了一步往 I 2 C I^2C I2C设备中写入数据的步骤。这个写入的数据也就是第三个参数。再或者这么说,write_byte_data(),直接完成了一次 I 2 C I^2C I2C的通信。

read()write()比较,发现,read()是通过write_byte()发送控制字+read_byte()读取数据打出的一套从 I 2 C I^2C I2C设备取值的组合拳,而write()只是用了write_byte_data()就完成了一整套往 I 2 C I^2C I2C设备中写数据的招式。

这些弄懂了,看代码就小意思了吧!

以上。

晚上手打,错误难免,请大家指正!

  • 13
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值