Python中的十六进制到pysical变量

时间:2017-03-02 15:37:47

标签: python hex gpio i2c

我为Raspberry Pi购买了MCP23017,以增加GPIO引脚。

enter image description here

在你们的帮助下,我能够安装和阅读设备。这意味着,我已经与MCP23017接口并将总线设置为0x20,因为我将A0-A3接地。然后,我使用上拉电阻设置了GPA和GPB。

该脚本如下所示:

import smbus
import time

mcp = 0x20

address_map = {
    0x12: 'GPIOA', 0x13: 'GPIOB',
}
register_map = {value: key for key, value in address_map.iteritems()}
max_len = max(len(key) for key in register_map)

def print_values(bus):
        for addr in address_map:
                value = bus.read_byte_data(mcp, addr)
                print "%-*s: 0x%02X" % (max_len, address_map[addr], value)

bus = smbus.SMBus(1)
bus.write_byte_data(mcp, int(12), 0xFF)
bus.write_byte_data(mcp, int(13), 0xFF)

while True:
    print_values(bus)
    time.sleep(0.1)

如果没有任何连接,这将以每行的十六进制打印出GPA或GPB:

>>> GPIOA = 0xFF
>>> GPIOB = 0xFF

但是如果我将GPB0连接到GND,它就变成了:

>>> GPIOA = 0xFF
>>> GPIOB = 0xFE

所以问题是,我怎样才能从这个Hex(0000 0000 1111 1110)中分配一个字典,以便告诉哪个引脚是哪个?

1 个答案:

答案 0 :(得分:1)

您可以使用bitstruct

>>> GPIOA = 0xf0
>>> gpa = list(reversed(bitstruct.unpack('b1'*8, chr(GPIOA))))
>>> gpa
[False, False, False, False, True, True, True, True]
>>> gpa[3]
False
>>> gpa[4]
True
>>> GPIOA = 0x18
>>> gpa = list(reversed(bitstruct.unpack('b1'*8, chr(GPIOA))))
>>> gpa[5]
False
>>> gpa[4]
True
>>> gpa
[False, False, False, True, True, False, False, False]

这允许您按索引访问位。不幸的是,你必须将索引的结果反转为正确,但它确实有效。

还有一种手动方式:

>>> gpa = [False]*8
>>> GPIOA = 0xf0
>>> for i in range(8):
...     gpa[i] = bool((1 << i) & GPIOA)
... 
>>> gpa
[False, False, False, False, True, True, True, True]

使用任何一种方法,您都可以将其放入如下字典中:

>>> names = ['GPIOA0', 'GPIOA1', 'GPIOA2', 'GPIOA3', 'GPIOA4', 'GPIOA5', 'GPIOA6', 'GPIOA7']
>>> gpadict = dict(zip(names, gpa))
>>> gpadict
{'GPIOA4': True, 'GPIOA5': True, 'GPIOA6': True, 'GPIOA7': True, 'GPIOA0': False, 'GPIOA1': False, 'GPIOA2': False, 'GPIOA3': False}