STM32H723- DMA DAC 仅适用于 const 吗?

Posted

技术标签:

【中文标题】STM32H723- DMA DAC 仅适用于 const 吗?【英文标题】:STM32H723- DMA DAC only works with const only? 【发布时间】:2021-07-05 22:59:21 【问题描述】:

在 STM32G4 中,我能够设置 DAC DMA,以便我可以使用常规变量(即 uint8_t 数组)。但是,当我尝试将代码移植到 H723 时,DAC DMA 将无法工作,除非它使用在运行时之前设置的常量变量(即 const uint8_t 数组)。我的应用程序需要对数组进行运行时更改。数组的指针初始化似乎不起作用。我想知道是否有办法解决这个问题?我是否坚持使用常量变量?谢谢!

EDIT1:DAC DMA 和 TIMER 的当前设置

static void MX_DAC1_Init(void)
  DAC_ChannelConfTypeDef sConfig = 0;
  hdac1.Instance = DAC1;
  if (HAL_DAC_Init(&hdac1) != HAL_OK)
    Error_Handler();
  
  sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
  sConfig.DAC_Trigger = DAC_TRIGGER_T15_TRGO;
  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
  sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_ENABLE;
  sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
  if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_2) != HAL_OK)
  
    Error_Handler();
  

Timer15 配置:

static void MX_TIM15_Init(void)
 TIM_ClockConfigTypeDef sClockSourceConfig = 0;
  TIM_MasterConfigTypeDef sMasterConfig = 0;

  htim15.Instance = TIM15;
  htim15.Init.Prescaler = 55-1;
  htim15.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim15.Init.Period = 10-1;
  htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim15.Init.RepetitionCounter = 0;
  htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim15) != HAL_OK)
  
    Error_Handler();
  
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim15, &sClockSourceConfig) != HAL_OK)
  
    Error_Handler();
  
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim15, &sMasterConfig) != HAL_OK)
  
    Error_Handler();
  

DMA 配置:

static void MX_DMA_Init(void)
 __HAL_RCC_DMA1_CLK_ENABLE();

  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
  /* DMAMUX1_OVR_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMAMUX1_OVR_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMAMUX1_OVR_IRQn);


在主函数中:

int main(void)
  MX_DAC1_Init();
  MX_TIM15_Init();
  MX_OPAMP2_Init();
  
  /* USER CODE BEGIN 2 */
  set_sine(dac_data1, NUM_DAC_POINTS) //Set a max amplitude uniformly over number of points, dac_data is initialized as uint8_t dac_data1[NUM_DAC_POINTS];
  HAL_TIM_Base_Start(&htim15); //Start the timer for DAC DMA Transfer
  HAL_DAC_Init(&hdac1);
  (HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t *)dac_data1, NUM_DAC_POINTS, DAC_ALIGN_8B_R);

此设置不起作用,但只需将 dac_data1 初始化为 const uint8_t 并预定义它,DMA 就可以工作。

【问题讨论】:

如果 DMA 无法从 RAM 中获取数据,它就会变得毫无用处。您的配置中可能存在一些错误。您需要提供更多详细信息。 一些 STM32 部件具有不同的内存库,核心耦合内存 (CCM) 可由处理器使用,但不能由 DMA 使用。对照参考手册检查地址,看看它对应于哪个银行。 在构建分析器中,dac_data1 在 RAM (0x2000002c) 上。 ITCMRAM、RAM_D1、RAM_D2 和 RAM_D3 都是空的。在参考手册(H723 为 RM0468)中,我找不到对“CCM”、“核心耦合内存”或“CCMRAM”的任何引用。是否有专门针对 h723 的 CCM 的数据表或网页?我可以在网上找到的所有链接都来自第三方站点和/或不同的目标 MCU。再次感谢! @TomV H7 系列中的所有 RAMS可由 DMA 访问。这是一条虚假信息。它有 3 个 DMA 控制器,你需要链接两个来访问一些内存。但这是可行的——我是在熟悉 H7 家族的时候自己做的。 我说的是“一些 STM32 部件”而不是 H7。我说的是正确的,但不是直接回答这个问题,这就是我发表评论的原因。尽管如此,它还是帮助 OP 找到了自己的答案。 【参考方案1】:

好的,感谢 Tom V 对不同记忆库的见解。在我的例子中,dac_data1 放在参考手册上的RAM 上,也称为DTCMRAMDTCMRAM 无法被 DMA 访问,但被选为 H7 上运行时操作的默认内存位置。需要修改链接器文件(在我的情况下,..._FLASH.ld 和 ..._RAM.ld)。我将 .bss、.data 和 ._user_heap_stack 内存位置从 RAM 更改为 RAM_D1。这直接取自:https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices

【讨论】:

没问题!如果问题现在已解决,您应该在您自己的答案旁边标记绿色勾号。

以上是关于STM32H723- DMA DAC 仅适用于 const 吗?的主要内容,如果未能解决你的问题,请参考以下文章

STM32cubemx教程 DAC+TIM+DMA

STM32cubemx教程 DAC+TIM+DMA

2019 8 8 STM32F407DAC DMA通道生成周期1msSIN波(1um一个点)相关配置

STM32 TIM DAC 和 DMA

重学STM32---DAC+DMA+TIM

STM32CubeMX(07)定时器+ DAC+DMA输出阶梯波实验。