RP2040 PICOSDK食用指南——DMA4读取MT6701角度数据

bool MT6701::DMA_READ()
{
    dataChannelRX = dma_claim_unused_channel(true); // 初始化 DMA 通道 (如果需要)
    dataChannelTX = dma_claim_unused_channel(true); 

    dma_channel_config SPI_DMA_RX_CONFIG = dma_channel_get_default_config(dataChannelRX); // 配置 DMA 通道 ,后面那个大的结构体就是具体配置详情
    dma_channel_config SPI_DMA_TX_CONFIG = dma_channel_get_default_config(dataChannelTX);

    //接受数据通道
    channel_config_set_transfer_data_size(&SPI_DMA_RX_CONFIG, DMA_SIZE_8); // 设置数据大小为 32 位
    //true: 表示请求的是 发送 (TX) 方向的 DREQ 信号。若为 false 则表示接收 (RX) 方向
    channel_config_set_dreq(&SPI_DMA_RX_CONFIG, spi_get_dreq(SPI_PORT, false)); // DREQ 来自 SPI RX  
    channel_config_set_read_increment(&SPI_DMA_RX_CONFIG, false);   // 设置读取地址递增
    channel_config_set_write_increment(&SPI_DMA_RX_CONFIG, true); // 向缓冲区的写入地址递增

    // 设置 DMA 通道的配置
    dma_channel_configure(
        dataChannelRX, 
        &SPI_DMA_RX_CONFIG,
        rxBuf,                       // 目标地址: 接收数据的缓冲区
        &spi_get_hw(SPI_PORT)->dr,   // 源地址: SPI 数据寄存器
        3,                           // 传输数据量 (3 个字节)
        false                        // 不立即启动
    );

    channel_config_set_transfer_data_size(&SPI_DMA_TX_CONFIG, DMA_SIZE_8); // 设置数据大小为 8 位
    channel_config_set_read_increment(&SPI_DMA_TX_CONFIG, false);  // 设置读取地址不递增
    channel_config_set_write_increment(&SPI_DMA_TX_CONFIG, true); // 设置写入地址递增
    //channel_config_set_chain_to(&SPI_DMA_TX_CONFIG, dataChannelRX); // 设置链式传输到接收通道

    dma_channel_configure(
        dataChannelTX, 
        &SPI_DMA_TX_CONFIG,
        &spi_get_hw(SPI_PORT)->dr,   // 目标地址: SPI 数据寄存器
        &MT6701_READ_CMD,             // 源地址: 发送数据的缓冲区
        3,                           // 传输数据量 (3 个字节)
        false                        // 不立即启动
    );

    csSelect(); // 选择芯片,开始通信
    // 启动DMA传输 (同时启动TX和RX以实现全双工)
    dma_start_channel_mask((1u << dataChannelTX) | (1u << dataChannelRX));

    // 等待DMA传输完成
    dma_channel_wait_for_finish_blocking(dataChannelTX); // 等待发送通道完成
    dma_channel_wait_for_finish_blocking(dataChannelRX); // 等待接收通道完成

    csDeselect(); // 取消选择芯片,结束通信
    /*
    dma_channel_set_irq0_enabled(dataChannelRX, true); // 告诉DMA在通道完成一个块时触发IRQ线0
    irq_set_exclusive_handler(DMA_IRQ_0, [this]() {
        // 处理 SPI 中断
        // 这里可以添加处理逻辑,例如读取数据或处理状态
        DMARequest(); // 调用 DMARequest 来处理数据
    });
    irq_set_enabled(DMA_IRQ_0, true); // 启用 DMA 中断
    */

    // 手动拉高DMA通道
    dma_channel_unclaim(dataChannelTX);
    dma_channel_unclaim(dataChannelRX);

    return true; // 返回 true 表示 DMA 请求已设置
}

为了让出CPU还是尽量使用PIO控制

posted @ 2025-07-07 19:48  mcwhirr  阅读(24)  评论(0)    收藏  举报