c++ - memcpy 命令在复制时交替数据

标签 c++ c embedded stm32 microcontroller

我正在使用 STM32 G474 用它的内部 DAC 创建一个波形。我为直接内存访问 (DMA) 模块提供了一个查找表,它在正确的时间将值提供给相应的 DAC channel 。听起来困难的部分实际上非常简单,并且工作得很好。

#define NS  64                             # number of samples

uint32_t Wave_Low[NS] = {2048,[...],2047};  # lookup table

int main(void)
{
HAL_DAC_Start_DMA( &hdac2,   DAC_CHANNEL_1, (uint32_t*)Wave_High, NS, DAC_ALIGN_12B_R);
*/ start DMA       use DAC2  channel 1  */
}
作为下一步,我想更改代码中的信号形式。由于我希望这种情况不会中断,因此停止 DMA 并重新初始化它不起作用(中间有 500 µs 的延迟而没有信号)。因此我需要覆盖查找表。我试过这样:
#define NS  64                             # number of samples

uint32_t Wave_Low[NS] = {2048,[...],2047};  # lookup table 1
uint32_t Wave_High[NS] = {4096,[...],4067}; # lookup table 2
uint32_t Wave_Active[NS];                  #used lookup table

int main(void)
{  
memcpy(Wave_Active , Wave_High, NS );      #assign high wave as the currently used one

HAL_DAC_Start_DMA( &hdac2,   DAC_CHANNEL_1, (uint32_t*)Wave_Active, NS, DAC_ALIGN_12B_R);
*/ start DMA       use DAC2  channel 1  */
}
据我了解,这段代码应该显示完全相同的行为,但 DAC 信号通过显示锯齿信号的正部分而不是它应该显示的中心正弦波而显着不同。我对嵌入式 C 有点生疏,但这种行为确实让我很恼火。

最佳答案

几个问题:

  • DMA 缓冲区需要为 volatile合格或否则编译器在生成访问它们的代码时可能会失败。
  • 您使用 memcpy不正确,应该是 memcpy(Wave_Active , Wave_High, sizeof Wave_Active);
  • 使用memcpy当涉及到与硬件相关的编程时,首先通常是不正确的。复制 256 个字节需要很长时间。最坏的情况是,您的 DAC 甚至可能会在您完成复制之前请求新数据。
    编写此类代码的正确方法是分配多个缓冲区,然后交换一个“事件”指针以指向所使用的缓冲区。由于我不理解这些数组的目的的免责声明,这样的事情将是一个巨大的速度优化:
      volatile uint32_t Wave_Low[NS] = {2048,[...],2047};  # lookup table 1
      volatile uint32_t Wave_High[NS] = {4096,[...],4067}; # lookup table 2
      volatile uint32_t* Wave_Active = Wave_High;
    
      ...
      if(DMA_flag)
      {
        Wave_Active = (Wave_Active==Wave_Low) ? Wave_High : Wave_Low;
    
        /* you might have to tell the DMA which array to use next time here */
      }
    
  • 关于c++ - memcpy 命令在复制时交替数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65828938/

    相关文章:

    c - 如何检索存储在无符号变量中的有符号值

    c - 如何检查 ARM 架构上的 C 应用程序中的内存泄漏

    c++ - 从使用 Wix 制作的 MSI 生成文本

    c - 定位 RAM 变量的 ROM 地址

    c++ - 使用 Nuget 在 Visual Studio 2019 中安装 Boost v1.70

    c - 字符串比较功能正常

    c - 我的第二个 Scanf() 被跳过

    c - 在嵌入式 C 中处理小数

    c++ - 处理返回 std::string 的函数中的异常

    c++ - 将旧的 Opencv 代码转换为新的 C++ API,替代 cvGetSubRect?