关于树莓派pico和circuitpython的更多玩法,请看树莓派pico专栏
uart使用见这篇文章
调用circuitpy的busio模块来使用,除此以外,uart、iic等要需要使用该模块,使用方法见及详细信息见这篇文章
收发数据的格式是字节数组bytearray,该类型要求数据不可变,因此如果要修改,需要额外新建,然后将其转换为字节数组。
然后是注意bytearray方法,它要求输入参数是可迭代对象,建议使用列表。
代码
python">import busio
from board import *
import sys# 初始化 SPI 时捕获异常
try:spi = busio.SPI(clock=GP10, MOSI=GP11, MISO=GP12)print("SPI initialized successfully.")
except Exception as e:print(f"Failed to initialize SPI: {e}")sys.exit(1) # 使用 sys.exit() 退出程序# 尝试获取 SPI 锁
if spi.try_lock():print("SPI lock acquired successfully.")
else:print("Failed to acquire SPI lock. Exiting.")spi.deinit() # 释放 SPI 资源sys.exit(1)try:# 配置 SPI 参数(根据实际需求调整波特率等参数)spi.configure(baudrate=1000000)# 发送数据data_to_send = b"hello"print(f"Sending data: {data_to_send}")# 接收数据(假设从设备返回相同长度的数据)buffer = bytearray(len(data_to_send))spi.write_readinto(data_to_send,buffer)print(f"Received data: {buffer}")finally:# 释放锁并反初始化 SPIspi.unlock()spi.deinit()print("SPI lock released and SPI deinitialized.")
初始化和释放
在初始化时,使用busio.SPI()方法创建SPI对象,参数列表为时钟、MOSI、MISO、半双工,可以参考引脚图选择功能引脚。支持3-4 线串行协议,最少提供时钟和发送引脚。
class busio.SPI(clock: microcontroller.Pin, MOSI: microcontroller.Pin | None = None, MISO: microcontroller.Pin | None = None, half_duplex: bool = False)
half_duplex
仅在 STM 上可用;其他芯片没有硬件支持。
deinit()→ None
关闭释放 SPI 总线,引脚可以用于其他功能
持有锁和释放锁
在spi和i2c通信时,需要获取锁来保证通信不受干扰和打断
try_lock()→ bool
尝试获取 SPI 锁,成功时返回 True。
unlock()→ None
释放 SPI 锁。
在进行设置以及通信时需要获取锁,并在用完后释放
发送和接收
只限于作为主设备的情况,circuitpython以及micropython对于spi从设备没有提供支持,但是你可以通过pio功能来实现从机功能
write(buffer: circuitpython_typing.ReadableBuffer, *, start: int = 0, end: int = sys.maxsize)→ None
写入 buffer
中的数据。SPI 对象必须被锁定。如果缓冲区为空,则不执行任何操作。
如果提供了 start
或 end
,则缓冲区将按 buffer[start:end]
传递的方式被切片,但不会复制数据。写入的字节数将是 buffer[start:end]
的长度。
参数:
-
buffer (ReadableBuffer)
从此缓冲区写入字节 -
start (int)
缓冲区切片的起始位置 -
end (int)
缓冲区切片的末尾;如果未指定,则使用len(buffer)
readinto(buffer: circuitpython_typing.WriteableBuffer, *, start: int = 0, end: int = sys.maxsize, write_value: int = 0)→ None
读取 buffer
,同时为每个读取的字节写入 write_value
。SPI 对象必须被锁定。如果要读取的字节数为 0,则不执行任何操作。
如果提供了 start
或 end
,则缓冲区将按如果传递了 buffer[start:end]
的方式被切片。读取的字节数将是 buffer[start:end]
的长度。
参数:
-
buffer (WriteableBuffer)
将字节读入此缓冲区 -
start (int)
缓冲区切片的起始位置 -
end (int)
缓冲区切片的末尾;如果未指定,则等同于len(buffer)
的值,对于任何提供的值,它将取min(end, len(buffer))
的值 -
write_value (int)
读取时写入的值
write_readinto(out_buffer: circuitpython_typing.ReadableBuffer, in_buffer: circuitpython_typing.WriteableBuffer, *, out_start: int = 0, out_end: int = sys.maxsize, in_start: int = 0, in_end: int = sys.maxsize)→ None
同时将数据写入 out_buffer
,并从 in_buffer
读取数据。SPI 对象必须被锁定。
如果提供了 out_start
或 out_end
,则缓冲区将按 out_buffer[out_start:out_end]
传递的方式被切片,但不会复制数据。写入的字节数将是 out_buffer[out_start:out_end]
的长度。
如果提供了 in_start
或 in_end
,则输入缓冲区将按 in_buffer[in_start:in_end]
传递的方式被切片,读取的字节数将是 out_buffer[in_start:in_end]
的长度。
切片的长度必须由 out_buffer[out_start:out_end]
和 in_buffer[in_start:in_end]
定义相等。如果缓冲区切片长度都为 0,则不执行任何操作。
参数:
-
out_buffer (ReadableBuffer)
从此缓冲区写入字节数据 -
in_buffer (WriteableBuffer)
将字节读入此缓冲区 -
out_start (int)
out_buffer
切片的起始位置 -
out_end (int)
out_buffer
切片的结束;如未指定,则使用len(out_buffer)
-
in_start (int)
in_buffer
切片的起始位置 -
in_end (None)
结束位置in_buffer slice
; 如果未指定,使用len(in_buffer)
这里写入和读取都是通过发送数据实现,也就是说,把发送和接收引脚短接进行实验时,使用write和readinto都是不能看到实验现象的,这和spi通信的特点有关,在读取接收的数据时,是写入数据发送,这样就可以接收到从机发送的数据,所以是读取的从机还没有发送的数据,而使用write_readinto就可以看到通信实验现象,因为它同时进行写入和读取操作。