RP2040(树莓派Pico) I2C/SPI/UART

这可以说是三个最常用的通信外设,他们的本质都一样,发送字节(这不是废话,以太网也是发送字节啊,只不过有规范.),他们只需要暴漏几个函数,读/写以及其他辅助函数,例如初始化/中断.

I2C技术参数:

  • 主从模式 (默认主机,从机地址0x55,主机支持10B寻址)
  • 标准(100kHz),快速(400kHz),快速Plus(1MHz)
  • 自带收发缓冲区 (深度各16个元素)
  • DMA/IRQ (正常标配)
  • Synopsys IP (买的牛逼IP,树莓派没设计.)

SPI技术参数:

  • 硬件CS支持 (主机从机都可以用)
  • 分布到芯片的很多引脚上 (看Pinout就知道)
  • 支持多种SPI模式 (TI/NI/摩托罗拉)
  • 自带FIFO (深度8 * 32B)
  • 支持4B – 16B传输帧 (但是需要考虑FIFO问题)
  • DMA/IRQ/突发传输支持 (正常标配)
  • 可以用作从机 (但是没有例子)
  • 频率支持(主机):Fperi/65024 ~ Fperi/2 (在标准125MHz下,即约2kHz到约75MHz)
  • 频率支持(从机):Fper/65024 ~ Fperi/12 (在标准125MHz下,即约12kHz到约75MHz)
  • 2组SPI (都可以自由用)
  • PL022 公版IP (ARM白送IP,树莓派自己没设计.)

UART技术参数:

  • 硬件流控 (CTS,RTS,官方图片没有写,实际有引出.)
  • 自带FIFO (TX深度:8 * 32B,RX深度:12 * 32B)
  • 可编程波特率:Fperi/1048560 ~ Fperi/16 (在标准125MHz下,即约120bps ~ 7812Kbps)
  • 可编程位数 (5,6,7,8 BIT + 1,2 STOP)
  • 2组UART (UART0通常用于stdio,UART1可以自由使用.)
  • DMA/IRQ (正常标配)
  • PL011 公版IP (ARM白送IP,树莓派自己没设计.)

I2C软件上可以防止因为无设备的锁死,但是如果发生其他类型的锁死,还得使用防锁死的函数,但是要解决锁死状态,需要重置IO状态信息.其关键函数如下,其中nostop如果为true,则不发送stop,用于restart很有用.

  • int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop);
  • int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop);

SPI基本测试代码:


int main() {
    uint8_t buf1 = 0xAA;
    uint8_t buf2[2] = {0xA5,0x5A};

    spi_init(spi0, 1000 * 1000);
    spi_set_format(spi0,8,SPI_CPOL_0,SPI_CPHA_0,SPI_MSB_FIRST);
    gpio_set_function(PIN_MISO, GPIO_FUNC_SPI);
    gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);
    gpio_set_function(PIN_CS,GPIO_FUNC_SPI);

    for(;;){
        sleep_ms(5);
        spi_write_blocking(spi0, &buf1, 1);
        sleep_ms(5);
        spi_write_blocking(spi0, buf2, 2);
    }

    return 0;
}

另外由于FRF是没有函数设置的,所以我们要手动设置.

hw_write_masked(&spi_get_hw(spi0)->cr0,0 << SPI_SSPCR0_FRF_LSB,SPI_SSPCR0_FRF_BITS);

默认受硬件CS时候,时序结果是这样的.(不同FRF不同,具体参考手册.)

如果需要一个CS下连续发送数据,那么还要人工操作CS,但其实依然做不到最大带宽,感觉是设计缺陷.

UART本身配置在例子里面已经说的很清楚,如果我们要阻塞发送一个字节可以用uart_putc_raw函数来完成,另外读取函数都没有超时控制,所以要自己处理好.


OK,之前已经把所有的主机模式都说了,UART不分主从,因为这里没寻址模式,I2C和SPI都分,I2C部分的从机描述,从手册4.3.10.1.2开始,SPI部分的从机描述从4.4.3.15开始,由于SDK还没完善,现在只能用标志位判断各种先写着了.

发表评论

邮箱地址不会被公开。 必填项已用*标注