定时周期内dma持续捕获上升沿个数,CPU读取时是否需要先停止dma,读取后再开启

使用dma捕获传感器高频计数值,当CPU读取存储器内的计数值时,是否一定需要先将dma停止,读取完成以后再开启dma,不这样会不会使CPU与dma之间产生冲突,使得计数值出现错误?

不需要在每次CPU读取时停止DMA,除非在DMA捕获过程中修改DMA配置

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 请看👉 :DMA是什么?——帮 CPU 跑腿的 DMA
  • 除此之外, 这篇博客: DMA基本工作原理总结概述(一)——DMA系统架构中的 五. 使用DMA的原因: 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    a. 把比较固定的任务让DMA来做,可以减轻CPU负担,提高系统的效率

    b. DMA具有一般CPU没有的高效操作,提高系统的吞吐率

  • 以下回答来自chatgpt:

    根据以上参考资料和个人的理解,回答该问题:

    在使用DMA持续捕获传感器高频计数值时,不需要暂停DMA,可以让DMA控制器和CPU同时访问内存,因为DMA控制器和CPU之间的访问是通过总线控制器协调的,并且DMA方式是由系统总线中一个独立的模块完成,不需要处理器参与,因此只有在开始和结束时,处理器才会参与。CPU只需要在需要读取存储器中计数值时,根据地址寄存器(AR)和字计数器(WC),向存储器发送读取请求,等待存储器返回读取数据即可。需要注意的是,在存储器到存储器的传送方式下,需要使用临时寄存器保存从源存储单元读出的数据,在读取完成后再写入到目的存储单元,传输完成后,临时寄存器只会保留最后一个字节,可由CPU读出。具体实现代码如下:

    // DMA传输初始化
    // 以SPI的RX模式为例,以下为示意代码
    void DMA_init(){
      // 选择DMA通道,由于在MCU中有多个DMA通道,需要在此进行选择和初始化
      DMA_CH = 0;
    
      // 设置DMA传输数据量
      DMA_TX_SIZE = 1000; // 假设要传输1000个数据
    
      // 设置DMA通道和DMA请求源
      DMA_CH_SRC = SPI_RX_REQ; // 假设SPI的RX模式对应的DMA请求源为SPI_RX_REQ
    
      // 设置DMA通道和DMA传输方向
      DMA_CH_DIR = MEM_TO_PERIPH; // 假设要将数据从存储器传输到外围设备
    
      // 设置DMA传输的存储器地址和外围设备地址
      DMA_ADDR_SRC = (uint32_t)&data_buf; // data_buf为存储器中的数据缓冲区
      DMA_ADDR_DEST = (uint32_t)&periph_device; // periph_device为外围设备的地址
    
      // 使能DMA控制器
      DMA_CTRL = DMA_EN;
    }
    
    // 读取存储器中的计数值
    uint32_t get_count_value(){
      // 对存储器中的计数值进行读取
      uint32_t count_value;
      count_value = *(uint32_t *)(MEMORY_ADDR); // 假设存储器中计数值的地址为MEMORY_ADDR
    
      // 返回读取的计数值
      return count_value;
    }
    

    需要注意的是,以上为示意代码,需要根据具体情况作出相应的调整和优化。如果在实际实现中遇到问题,也可以参考以上的参考资料进行排查和解决。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^