前言
本文仅是对MaxiPy官方文档的整理与总结,自学请看官方文档,侵权即删MaixCAM MaixPy 快速开始 - MaixPy
1.GPIO
以基本点灯代码为例进行说明
python
from maix import gpio, pinmap, time
pinmap.set_pin_function("A14", "GPIOA14")
led = gpio.GPIO("GPIOA14", gpio.Mode.OUT)
led.value(0)
while 1:
led.toggle()
time.sleep_ms(500)
下面逐行逐参数进行介绍
导入模块
from maix import gpio, pinmap, time 从 MaixPy 标准固件里导入 3 个模块/类
gpio :控制 GPIO 电平、方向、中断等功能
pinmap :把芯片引脚复用到想要的"功能名字"
time :延时函数,单位可以是 us、ms、s
pinmap.set_pin_function("A14", "GPIOA14")
功能:把物理引脚 A14 的复用功能设成 GPIOA14。
参数:
• "A14" ------ 芯片封装上的物理引脚名(IO 口 A 组的第 14 号)
• "GPIOA14" ------ 想要映射成的"功能名字";Maix 固件里每个功能都有字符串标识,这个名字正好对应 GPIO 功能。之后用 "GPIOA14" 去创建 gpio 对象,就会真正操作到 A14 这根线。
led = gpio.GPIO("GPIOA14", gpio.Mode.OUT)
创建 GPIO 对象,并初始化方向。
参数:
• "GPIOA14" ------ 上一步映射好的名字,告诉驱动操作哪根线
• gpio.Mode.OUT ------ 枚举常量,表示把该引脚设为输出模式(output),可以驱动 LED。
返回值:led 是一个 gpio.GPIO 实例,后续通过它读写电平。
led.value(0)
把引脚电平拉低(0 = 低电平)
led.toggle()
把当前电平翻转一次
time.sleep_ms(500)
延时 500 毫秒(半秒)
2.按键
电赛中视觉模块按键使用较少,不详述,请见官方文档
MaixCAM MaixPy 按键事件使用 - MaixPy
3.UART
一个注意点:
MaixCAM 的 TX
(UART0
) 引脚在开机时不能是被拉低 的状态,不然会导致无法开机,是芯片的特性,如果你在做 3.3v
转 5v
的电平转换电路要十分注意不要默认拉低请保持浮空(可以考虑使用电平转换芯片)。以及如果你发现无法开机,也可以先检查一下 TX
是否被拉低了。
数据的发送
python
bytes_content = b'\x01\x02\x03'
serial.write(bytes_content)
主要有两个函数write_str
和write
函数。
write_str
函数来发送字符串 ,write
用来发送字节流 ,即str
和bytes
类型,两者可以互相转换,比如:
-
"A"
调用encode()
方法变成b"A"
,反过来b"A"
调用decode()
方法变成"A"
。 -
str
没法显示一些不可见字符比如 ASCII 码中的值0
,在字符串中也是\0
一般作为结束符,在bytes
类型中就可以用b"\x00"
来储存。 -
对于非 ASCII 编码的字符串更有用,比如
UTF-8
编码中中文好
是由三个字节\xe5\xa5\xbd
来表示的,我们可以通过"好".encode("utf-8")
得到b"\xe5\xa5\xbd"
,也可以通过b'\xe5\xa5\xbd'.decode("utf-8)
得到"好"
。
所以对于 str
类型,也可以不用write_str
,而是使用serial.write(str_content.encode())
来发送。
数据的接收
使用read
方法进行读取数据,直接:
python
while not app.need_exit():
data = serial.read()
if data:
print(data)
time.sleep_ms(1)
同样,read
方法获得的数据也是**bytes
** 类型,这里read
会读取对方一次性发送的一串数据,如果没有数据就是b''
即空字节。
这里用了time.sleep_ms(1)
进行睡眠了1ms
,用来释放 CPU,不让这个线程占用所有 CPU 资源,而且1ms
不影响我们程序的效率,特别是在多线程时有用。
另外read
函数有两个参数:
len
:代表想接收的最大长度 ,默认-1
代表缓冲区有多少就返回多少,传>0
的值则代表最多返回这个长度的数据。timeout
:- 默认
0
代表从缓冲区读取数据立马返回数据 ,如果len
为-1
则返回所有数据,如果指定了len
则返回长度不超过len
的数据。 <0
代表一直等待直到接收到了数据才返回 ,如果len
为-1
则等待到接收到数据才返回(一串连续接收到的数据,即阻塞式读取所有数据),如果指定了len
则等待接收数量达到len
才返回。>0
代表无论有没有接收到数据,超过这个时间就会返回。
- 默认
看起来有点复杂,常见的参数组合:
read()
: 即read(-1, 0)
,从缓冲区读取收到的数据,通常是对方一次性发来的一串数据,等到对方没有发送(一个字符的发送时间内没有再发)就立刻返回。read(len = -1, timeout = -1)
: 阻塞式读取一串数据,等到对方发送了数据并且一个字符的发送时间内没有再发才返回。read(len = 10, timeout = 1000)
: 阻塞式读取 10 个字符,读取到 10 个字符或者 超过 1000ms 还没收到就返回已经收到的数据。
设置接受回调函数
下面以官方例程为例进行解释
python
from maix import uart, app, time
def on_received(serial : uart.UART, data : bytes):
print("received:", data)
# send back
serial.write(data)
device = "/dev/ttyS0"
serial = uart.UART(device, 115200)
serial.set_received_callback(on_received)
serial.write_str("hello\r\n")
print("sent hello")
print("wait data")
while not app.need_exit():
time.sleep_ms(100) # sleep to make CPU free
导入模块
from maix import uart, app, time
从 MaixPy 固件中导入 3 个模块
uart :串口收发功能
app :应用管理,用来检测是否应退出(例如按下 HOME 键)
time :延时函数,单位 ms
具体回调函数的定义
def on_received(serial : uart.UART, data : bytes):
定义串口接收回调函数。
参数:
• serial : uart.UART ------ 触发本次回调的串口实例,方便在回调里直接操作该串口(读/写)
• data : bytes ------ 本次接收到的完整一帧数据(底层驱动已经帮你拼好),长度可变
功能:
把收到的内容原样打印到控制台
再用 serial.write(data) 回发(echo)
触发时机:
当 UART 接收缓冲区达到阈值(通常 1 Byte 或 FIFO 半满)或空闲中断时,底层 C 驱动会调用你在 Python 层注册的回调。
回调运行在一个独立线程(或中断上下文转线程),不会阻塞主循环。
指定串口
device = "/dev/ttyS0"
指定要使用的 Linux 设备节点(ttyS0 对应芯片的 UART0)。
serial = uart.UART(device, 115200)
创建 UART 对象
serial = uart.UART(device, 115200)
参数:
• device ------ 字符串,"/dev/ttyS0"
• 115200 ------ 波特率 115200 bps
其余参数保持默认:8N1(8 数据位,无校验,1 停止位),无流控。
设置回调函数
serial.set_received_callback(on_received)
把 on_received 函数注册为「接收完成回调」。
一旦底层有数据到达,驱动会在后台线程里自动调用 on_received(serial, data)。
若再次调用 set_received_callback(None) 可取消回调,回到轮询模式。
串口发送数据
serial.write_str("hello\r\n")
作用:以字符串形式发送 "hello\r\n"。
底层会转成 bytes 后发出。
主循环
while not app.need_exit():
主循环,仅做两件事:
周期性检测是否需要退出程序
通过 time.sleep_ms(100) 主动让出 CPU,降低功耗
注意:真正的数据接收全部发生在回调线程里,主循环无需轮询 serial.read()。
使用其他串口
以uart1为例
python
from maix import app, uart, pinmap, time
pinmap.set_pin_function("A18", "UART1_RX")
pinmap.set_pin_function("A19", "UART1_TX")
device = "/dev/ttyS1"
serial1 = uart.UART(device, 115200)
其他应用可跳转ButterflyBoy0大佬的使用教程[MaixCam]使用心得二:UART串口通信-CSDN博客