Helper:
fpioa_manager:
简介:
fpioa_manager:简称fm
,该模块用于注册芯片内部功能和引脚,帮助用户管理内部功能和引脚映射关系的功能模块。
K210 芯片上的 外部引脚 和 内部功能 是彼此独立的,引脚是指从芯片上引出的许多金属触点,也就是我们俗称的功能引脚,它可以是 GPIO / PWM / ADC / I2C 等内部功能引脚,传统的认知是引脚对应的内部功能是不可改变的,但可以复用的,而K210 是可以通过映射来改变引脚功能的,
使用:
调用 register 函数将 pin 引脚与具体的硬件功能(GPIO/I2C/UART/I2S/SPI)绑定起来,在不使用的时候调用 unregister 释放引脚所绑定的硬件功能
from fpioa_manager import fm
fm.register(11, fm.fpioa.GPIO0, force=True)
fm.register(12, fm.fpioa.GPIOHS0, force=True)
fm.register(13, fm.fpioa.UART2_TX)
fm.register(14, fm.fpioa.UART2_RX)
# other code
fm.unregister(11)
fm.unregister(12)
fm.unregister(13)
fm.unregister(14)
注意下面这些默认使用的:
还有以下引脚是开机默认注册使用的,非必要不要改它:
类 fm:
方法:
register(pin, func, force=True):
设置引脚(pin)对应的外设功能(func),默认启用强制绑定参数(force=True),它将强制更换指定的引脚功能,如果发现存在上一个绑定的引脚,则会发出一个警告,但不影响代码继续执行,如果设置为false,那么就会弹出异常。
from fpioa_manager import fm
fm.register(16, fm.fpioa.GPIO2)
fm.register(13, fm.fpioa.GPIO2)#GPIO2引脚映射到IO13
fm.register(12, fm.fpioa.GPIO2, force=False)
unregister(pin):
释放引脚(pin)上的硬件功能;
get_pin_by_function(pin):
获取引脚(pin)上绑定的硬件功能;
get_gpio_used():
获取所有 gpio 的使用情况,它只查询 GPIOHS / GPIO 的引脚分配情况, None 表示该硬件功能未被使用。
Board:
这是一个 MaixPy 板级配置模块,它可以在用户层统一 Python 代码,从而屏蔽许多硬件的引脚差异。
from Maix import GPIO
from fpioa_manager import fm
from board import board_info
print(board_info.LED_R)
fm.register(board_info.LED_R, fm.fpioa.GPIO0, force=True)
led_r = GPIO(GPIO.GPIO0, GPIO.OUT)
led_r.value(0)
这份代码的优点在于可以试用于所有的maixpy,不需要改源码,原因在于board_info.LED_R这个的引入保证了代码的一致性,简单来讲就是我们在配置这个Board的时候,已经将跟LED相连的IO的值赋给这个board_info.LED_R了,看下图:
Board配置方法:
将这个链接的代码copy出来,放到 IDE 编辑框中运行,即可完成对硬件配置项(config.json)的导入,它会在 flash 上存储该配置文件。
复制以下代码也行:
import json
config = {
"type": "bit",
"board_info": {
'BOOT_KEY': 16,
'LED_R': 13,
'LED_G': 12,
'LED_B': 14,
'MIC0_WS': 19,
'MIC0_DATA': 20,
'MIC0_BCK': 18,
}
}
cfg = json.dumps(config)
print(cfg)
try:
with open('/flash/config.json', 'rb') as f:
tmp = json.loads(f.read())
print(tmp)
if tmp["type"] != config["type"]:
raise Exception('config.json no exist')
except Exception as e:
with open('/flash/config.json', "w") as f:
f.write(cfg)
import machine
machine.reset()
不同板子不一样,具体看这里:Board - Sipeed Wiki
当然也可以导入人为自定义的模板
from board import board_info
board_info.load({
'PIN10': 10,
'BOOT_KEY': 16,
'WIFI_TX': 6,
'WIFI_RX': 7,
'WIFI_EN': 8,
})
print('PIN10:', board_info.PIN10)
print('BOOT_KEY:', board_info.BOOT_KEY)
print('WIFI_TX:', board_info.WIFI_TX)
print('WIFI_RX:', board_info.WIFI_RX)
print('WIFI_EN:', board_info.WIFI_EN)
调用结果
PIN10: 10
BOOT_KEY: 16
WIFI_TX: 6
WIFI_RX: 7
WIFI_EN: 8
FPIOA:
简介:
FPIOA是现场可编程 IO 阵列,K210 支持每个外设随意映射到任意引脚, 使用 FPIOA 功能来实现。
类 FPIOA:
方法:
help(func):
作用:返回外设的简要描述;
如:
fpioa.help(fpioa.JTAG_TCLK)
附录:外设表,就是这个表格对应的内容;
set_function(pin, func):
作用:设置引脚对应的功能, 即引脚映射;
比如 需要将连接 绿色 LED
的引脚映射到 高速 GPIO0
上:
fpioa = FPIOA()#创建类
fpioa.set_function(board_info.LED_G, fm.fpioa.GPIOHS0)
get_Pin_num(func):
作用:获取外设映射到哪个引脚上了
如:
fpioa = FPIOA()
fpioa.set_function(board_info.LED_G, fm.fpioa.GPIOHS0)
pin = fpioa.get_Pin_num(fm.fpioa.GPIOHS0)
if pin == board_info.LED_G:
print("set function ok")
GPIO:
简介:
K210上有高速 GPIO(GPIOHS) 和通用 GPIO,特点如下:只有GPIOHS支持中断
构造函数:
class GPIO(ID, MODE, PULL, VALUE)
创建一个GPIO对象
常量:
GPIO0: GPIO0
GPIO1: GPIO1
GPIO2: GPIO2
GPIO3: GPIO3
GPIO4: GPIO4
GPIO5: GPIO5
GPIO6: GPIO6
GPIO7: GPIO7
GPIOHS0: GPIOHS0
GPIOHS1: GPIOHS1
GPIOHS2: GPIOHS2
GPIOHS3: GPIOHS3
GPIOHS4: GPIOHS4
GPIOHS5: GPIOHS5
GPIOHS6: GPIOHS6
GPIOHS7: GPIOHS7
GPIOHS8: GPIOHS8
GPIOHS9: GPIOHS9
GPIOHS10: GPIOHS10
GPIOHS11: GPIOHS11
GPIOHS12: GPIOHS12
GPIOHS13: GPIOHS13
GPIOHS14: GPIOHS14
GPIOHS15: GPIOHS15
GPIOHS16: GPIOHS16
GPIOHS17: GPIOHS17
GPIOHS18: GPIOHS18
GPIOHS19: GPIOHS19
GPIOHS20: GPIOHS20
GPIOHS21: GPIOHS21
GPIOHS22: GPIOHS22
GPIOHS23: GPIOHS23
GPIOHS24: GPIOHS24
GPIOHS25: GPIOHS25
GPIOHS26: GPIOHS26
GPIOHS27: GPIOHS27
GPIOHS28: GPIOHS28
GPIOHS29: GPIOHS29
GPIOHS30: GPIOHS30
GPIOHS31: GPIOHS31
GPIO.IN: 输入模式
GPIO.OUT: 输出模式
GPIO.PULL_UP: 上拉
GPIO.PULL_DOWN: 下拉
GPIO.PULL_NONE: 即不上拉也不下拉
GPIO.IRQ_RISING: 上升沿触发
GPIO.IRQ_FALLING:下降沿触发
GPIO.IRQ_BOTH: 上升沿和下降沿都触发
方法:
value:
GPIO.value([value])
设置高低电平,返回值是当前GPIO引脚状态
irq:
GPIO.irq(CALLBACK_FUNC,TRIGGER_CONDITION,GPIO.WAKEUP_NOT_SUPPORT,PRORITY)
配置中断处理
CALLBACK_FUNC:中断回调函数,当中断触发的时候被调用,一个入口函数PIN_NUM ,PIN_NUM 返回的是触发中断的 GPIO 引脚号(只有GPIOHS支持中断,所以这里的引脚号也是GPIOHS的引脚号)
TRIGGER_CONDITION:GPIO 引脚的中断触发模式:GPIO.IRQ_RISING 上升沿触发 GPIO.IRQ_RISING 上升沿触发 GPIO.IRQ_RISING 上升沿触发
disirq:
GPIO.disirq()
关闭中断
mode:
GPIO.mode(MODE)
学完这两个外设后就可以开始点亮LED了
点亮LED:
看一眼原理图我们可以知道只需要让IO输出低电平就可以让灯亮
from Maix import GPIO#导入库
from fpioa_manager import fm
io_led_red = 13
fm.register(io_led_red, fm.fpioa.GPIO0)#将IO13映射为了GPIO0
led_r=GPIO(GPIO.GPIO0, GPIO.OUT)
led_r.value(0)#让引脚输出低电平
io_led_red = 13,红灯亮,14:蓝灯,12:绿灯
总结一下步骤:导入库->将IO口映射为GPIO->配置该GPIO状态->输出低电平
当然引入board会让代码变得更易于移植:
from Maix import GPIO#导入库
from fpioa_manager import fm
from board import board_info
fm.register(board_info.LED_R, fm.fpioa.GPIO0)#将IO13映射为了GPIO0
led_r=GPIO(GPIO.GPIO0, GPIO.OUT)
led_r.value(0)#让引脚输出低电平
流水灯:
from Maix import GPIO#导入库
from fpioa_manager import fm
from board import board_info
import utime
fm.register(board_info.LED_R, fm.fpioa.GPIO0)
fm.register(board_info.LED_B, fm.fpioa.GPIO1)
fm.register(board_info.LED_G, fm.fpioa.GPIO2)
led_r=GPIO(GPIO.GPIO0, GPIO.OUT)
led_b=GPIO(GPIO.GPIO1, GPIO.OUT)
led_g=GPIO(GPIO.GPIO2, GPIO.OUT)
while True:
led_r.value(0)
led_b.value(1)
led_g.value(1)
utime.sleep_ms(1000)
led_r.value(1)
led_b.value(0)
led_g.value(1)
utime.sleep_ms(1000)
led_r.value(1)
led_b.value(1)
led_g.value(0)
utime.sleep_ms(1000)
按键灯:
from Maix import GPIO#导入库
from fpioa_manager import fm
from board import board_info
import utime
fm.register(board_info.LED_B, fm.fpioa.GPIO1)
fm.register(board_info.BOOT_KEY, fm.fpioa.GPIO0)
led_b=GPIO(GPIO.GPIO1, GPIO.OUT)
key=GPIO(GPIO.GPIO0, GPIO.IN)
led_b.value(1)
while True:
if key.value()==0:
led_b.value(0)
utime.sleep_ms(1000)
break
按键中断:
import utime
from Maix import GPIO
from board import board_info
from fpioa_manager import fm
def test_irq(pin_num):#回调函数
print("key", pin_num, "\n")
fm.register(board_info.BOOT_KEY, fm.fpioa.GPIOHS1)
key = GPIO(GPIO.GPIOHS1, GPIO.IN, GPIO.PULL_NONE)
utime.sleep_ms(100)
key.irq(test_irq, GPIO.IRQ_BOTH, GPIO.WAKEUP_NOT_SUPPORT,7)
utime.sleep_ms(3000) # 在 3 秒内等待触发
UART:
uart 模块主要用于驱动开发板上的异步串口,可以自由对 uart 进行配置。k210 一共有3个 uart,每个 uart 可以进行自由的引脚映射。
import json
config = {
"type": "bit",
"board_info": {
'BOOT_KEY': 16,
'LED_R': 13,
'LED_G': 12,
'LED_B': 14,
'MIC0_WS': 19,
'MIC0_DATA': 20,
'MIC0_BCK': 18,
'UART_TX':9
'UART_RX':10
}
}
cfg = json.dumps(config)
print(cfg)
try:
with open('/flash/config.json', 'rb') as f:
tmp = json.loads(f.read())
print(tmp)
if tmp["type"] != config["type"]:
raise Exception('config.json no exist')
except Exception as e:
with open('/flash/config.json', "w") as f:
f.write(cfg)
import machine
machine.reset()
构造函数:
uart = machine.UART(uart,baudrate,bits,parity,stop,timeout, read_buf_len)
创建一个uart对象
方法:
init:
初始化对象,不过在创建对象的时候已经初始化了,这里用于重新初始化
uart.init(baudrate,bits,parity,stop,timeout, read_buf_len)
read:
用于读取串口缓冲中的数据
uart.read(num)
传入:num:读取字节的数量,一般填入缓冲大小
返回:bytes类型的数据
readline:
用于读取串口缓冲数据的一行
uart.readline(num)
传入:num:读取行的数量
返回:bytes类型的数据
write:
用于发送串口数据
uart.write(buf)
传入:需要发送的数据
返回:写入的数据量
deinit:
注销资源
repl_uart():
获取用于 REPL 的串口对象
返回:用于 REPL 的串口对象, 默认初始化位 115200 8 N 1
rt,baudrate,bits,parity,stop,timeout, read_buf_len)
创建一个uart对象
[外链图片转存中...(img-0HMsL0r9-1691423788823)]
## 方法:
### init:
初始化对象,不过在创建对象的时候已经初始化了,这里用于重新初始化
```none
uart.init(baudrate,bits,parity,stop,timeout, read_buf_len)
read:
用于读取串口缓冲中的数据
uart.read(num)
传入:num:读取字节的数量,一般填入缓冲大小
返回:bytes类型的数据
readline:
用于读取串口缓冲数据的一行
uart.readline(num)
传入:num:读取行的数量
返回:bytes类型的数据
write:
用于发送串口数据
uart.write(buf)
传入:需要发送的数据
返回:写入的数据量
deinit:
注销资源
repl_uart():
获取用于 REPL 的串口对象
返回:用于 REPL 的串口对象, 默认初始化位 115200 8 N 1