**这是本文档旧的修订版!**
可编程PIO的使用
来自TaterLi的博客文章
RP2040中有2个相同的PIO块,每个PIO块都有专用的连接到总线结构,GPIO和中断控制器.单个PIO块的示意图如图所示.
Pico的PIO Block的功能框图(1/2)
PIO是一种通用的硬件接口,它可以支持多种IO标准.包括实现以下功能:
8080/6080 并行接口 I2C I2S SDIO SPI/DSPI/QSPI UART DPI/VGA (利用电阻网络) PIO和处理器一样,都是可以编程的.有两个PIO块,每个块有四个状态机,可以独立执行顺序程序来操作GPIO和传输数据.与通用处理器不同的是,PIO状态机对IO的专业化程度很高(highly specialised),它注重确定性,精确的时序,并与固定功能硬件紧密结合.每个状态机都配备有以下内容:
- 两个32位移位寄存器 (任意方向/任意移位数)
- 两个32位临时寄存器
- 4 * 32B FIFO (双向) 或 8 * 32 FIFO (单向)
- 小数分频器 (16整数 + 8小数)
- 可编程GPIO映射
- DMA/IRQ
- 每个状态机及其支持的硬件,占用的硅面积与SPI/I2C大致相同.然而,PIO状态机可以动态地配置和重新配置,以实现许多不同的接口,自由度很高.
以类似软件的方式使状态机可编程,而不是像CPLD那样的完全可配置的逻辑结构,可以在相同的成本和功率范围内提供更多的硬件接口,这也为那些希望通过直接编程而不是使用PIO库中的预制接口来利用PIO的全部灵活性的人提供了一个更熟悉的编程模型和更简单的工具流程.
PIO具有很高的性能以及灵活性,这得益于每个状态机内部精心挑选的一组固定功能硬件.在输出DPI时,当使用48MHz系统时钟运行时,PIO可以在活动扫描线期间维持360Mb/s的速度.在这个例子中,一个状态机负责处理帧/扫描线时序和生成像素时钟,而另一个状态机负责处理像素数据,并解包运行长度编码的扫描线.
状态机的输入和输出最多可以映射到32个GPIO(RP2040限制为30个GPIO),所有状态机都可以独立地同时访问任何GPIO.例如,标准UART代码允许TX/RX/CTS/RTS成为任意四个GPIO.I2C允许SDA/SCL也是如此.可用的自由度取决于给定的PIO程序究竟如何选择使用PIO的引脚映射资源,但至少,一个接口可以自由地选择一些数量的GPIO.
四个状态机从一个共享指令存储器中执行,系统软件将程序加载到这个存储器中,配置状态机和IO映射,然后设置状态机运行.PIO程序的来源多种多样:
- 由用户直接组装
- 从PIO库中抽取
- 由用户软件编程生成
- 从这一点上看.状态机一般是自主的,系统软件通过DMA/IRQ和控制寄存器进行交互,与RP2040上的其他外设一样.对于比较复杂的接口,PIO提供了一套小而灵活的基元,使系统软件可以更多地亲自动手处理状态机控制流程.
Pico的PIO FIFO(1/2)
Pico的PIO输出移位寄存器(1/2)
Pico的PIO输入移位寄存器
Pico的PIO FIFO映射