Python 中物理变量的十六进制
Hexadecimals to pysical variables in Python
我为我的 Raspberry Pi 买了一个 MCP23017 来增加 GPIO 引脚。
在你们的帮助下,我能够安装和读取设备。这意味着,我已经与 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
所以问题是,我如何从这个十六进制 (0000 0000 1111 1110) 分配一个字典,以便我可以分辨出哪个引脚是哪个?
你可以使用 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}
我为我的 Raspberry Pi 买了一个 MCP23017 来增加 GPIO 引脚。
在你们的帮助下,我能够安装和读取设备。这意味着,我已经与 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
所以问题是,我如何从这个十六进制 (0000 0000 1111 1110) 分配一个字典,以便我可以分辨出哪个引脚是哪个?
你可以使用 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}