# 香橙派zero2 寄存器控制单个gpio(PC12_红灯)
前天无意间看到python环境下实现OrangePi Zero寄存器访问及GPIO控制
正好手里有块zero2,(还没有玩过这种操作寄存器的方式)。
下面是h616 gpio的寄存器
下面是控制寄存器
wiringOP中关于H3和H616 gpio寄存器的描述
下面是代码
root@orangepizero2:/home/orangepi/mytest/gpio# vim OPiZero2_GPIO.py
import mmap
import struct
class GPIO:
#-------------------------------------------------------------------------------------#
#定义GPIO相对0x0300B000的偏移地址
PIO_ADDR_OFFSET = 0x0000
#定义GPIOC的寄存器相对0x0300B000的偏移地址
#作者只写了GPIOC的寄存器定义,如果需要使用其他IO,请参考datasheet在下面增加定义
PIO_PC_CFG0_REG = PIO_ADDR_OFFSET + 2*0x0024+ 0x00
PIO_PC_CFG1_REG = PIO_ADDR_OFFSET + 2*0x0024+ 0x04
PIO_PC_CFG2_REG = PIO_ADDR_OFFSET + 2*0x0024+ 0x08
PIO_PC_CFG3_REG = PIO_ADDR_OFFSET + 2*0x0024+ 0x0C
PIO_PC_DATA_REG = PIO_ADDR_OFFSET + 2*0x0024+ 0x10
PIO_PC_DRV0_REG = PIO_ADDR_OFFSET + 2*0x0024+ 0x14
PIO_PC_DRV1_REG = PIO_ADDR_OFFSET + 2*0x0024+ 0x18
PIO_PC_PUL0_REG = PIO_ADDR_OFFSET + 2*0x0024+ 0x1C
PIO_PC_PUL1_REG = PIO_ADDR_OFFSET + 2*0x0024+ 0x20
#-------------------------------------------------------------------------------------#
#以下是构造函数和析构函数
def __init__(self):
self.m_mmap = None
self.fd = None
def __del__(self):
if(self.m_mmap != None):
self.m_mmap.close()
if(self.fd != None):
self.fd.close()
#-------------------------------------------------------------------------------------#
#以下是成员函数
def Init(self):
"""
GPIO初始化函数
函数会打开/dev/mem文件,并映射从0x0300B000地址开始,共4096字节长度(1页)的内存空间到用户的虚拟地址
返回值:无
"""
START_ADDR = 0x0300B000
self.fd = open("/dev/mem", "rb+")
self.m_mmap = mmap.mmap(self.fd.fileno(), 4096 * 1, mmap.MAP_SHARED, mmap.PROT_WRITE | mmap.PROT_READ, mmap.ACCESS_WRITE, START_ADDR)
assert self.m_mmap != None,"Init Fails"
def ReadReg(self,reg_addr):
"""
读取一个寄存器的值
reg_addr:要读取的寄存器地址(必须为4的倍数),且范围在1个pagesize内,即小于4096
返回值:寄存器的值(4字节)
"""
assert self.m_mmap != None,"Init Fails"
assert reg_addr%4 == 0,"reg_addr must be mutiple of 4"
assert 0<=reg_addr<=4096,"reg_addr must be less than 4096,which is 1 pagesize"
self.m_mmap.seek(reg_addr)
ReadBytes = self.m_mmap.read(4)
return struct.unpack('I',ReadBytes)[0]#注意这里的L换成了I!!!
def WriteReg(self,reg_addr,value):
"""
写一个寄存器的值
reg_addr:要写入的寄存器地址(必须为4的倍数),且范围在1个pagesize内,即小于4096
value:要写入的值,整形,一次写入四个字节长度的整数,即0xffffffff
返回值:无
"""
assert self.m_mmap != None,"Init Fails"
assert reg_addr%4 == 0,"reg_addr must be mutiple of 4"
assert 0<=reg_addr<=4096,"reg_addr must be less than 4096,which is 1 pagesize"
assert 0<=value<=0xFFFFFFFF,"value must be less than 0xFFFFFFFF,which is 4 bytes"
self.m_mmap.seek(reg_addr)
BytesToWrite = struct.pack('L',value)
self.m_mmap.write(BytesToWrite)
return
root@orangepizero2:/home/orangepi/mytest/gpio# vim LED_Blink.py
import OPiZero2_GPIO
import time
#以下为主程序
GPIO = OPiZero2_GPIO.GPIO()
GPIO.Init();
#PC12配置为输出模式
GPIO.WriteReg(GPIO.PIO_PC_CFG2_REG,GPIO.ReadReg(GPIO.PIO_PC_CFG2_REG) | 0x00010000)
while(1):
GPIO.WriteReg(GPIO.PIO_PC_DATA_REG,GPIO.ReadReg(GPIO.PIO_PC_DATA_REG) ^ 0x00001000)
time.sleep(0.3)
这两个文件放一块就可以
root@orangepizero2:/home/orangepi/mytest/gpio# python3 LED_Blink.py
参考:
wiringOP
python环境下实现OrangePi Zero寄存器访问及GPIO控制
Orange pi GPIO输出控制,裸机点灯大法(一)!