ST意法半导体
直播中

李进锋

7年用户 885经验值
私信 关注
[问答]

Nucleo-G431KB GPIO端口为什么不能被DMA接口定位为外设?

你好呀!
我刚刚开始使用 STM32CubeIDE,经过一段垂直的学习曲线后,我慢慢地掌握了它的大部分内容。
我想 DMA 到 GPIO,但似乎没有任何方法可以通过 .ioc GUI 界面执行此操作。GPIO 端口不能被 DMA 接口定位为外设,当您在 DMA 部分选择 MemToMem 选项时,STM32CubeIDE 生成的代码没有任何用户部分,因此实际上不能由用户编辑。
另一个问题是 MemToMem DMA 选项没有公开最有用的选项,如“循环”模式(它只公开“正常”),也没有提供提供任何触发器的选项。
我是否达到了 STM32CubeIDE 的极限?或者有什么方法可以通过我还没有见过的 STM32CubeIDE 接口来实现吗?
顺便说一句,我正在使用最新版本的 STM32CubeIDE。








回帖(1)

张琨

2023-2-7 11:35:17
> 令人沮丧的是界面如此接近,但并没有完全实现。
是的,我没有使用它是有原因的。
> 我希望 STM 打算扩展功能,而不是将其作为介绍程序让人们进入生态系统。
我认为他们应该首先修复假定存在的功能。更令人沮丧的是,即使是基本的时钟设置也被搞得一团糟,以至于 MCU 锁定牢固。
> 如果有人可以看一下,让我知道我做错了什么,那就太好了。
抱歉,我无法破译 HAL 代码。如果您发布相关的外设寄存器(RCC、DMA、DMAMUX、TIM8、GPIOA),我可能会注意到是否缺少某些内容。
> 我已经逐步完成了调试器,一切都按照您的预期进行了设置。DMA 地址和模式正确,一切都已初始化等。但似乎什么也没发生。
计时器是否正在运行,即 CNT 值是否发生变化?定时器或 DMA 状态寄存器中是否设置了任何标志?你能读回你设置的寄存器值吗?
> 数据表中没有任何内容表明这不可行。
数据表和参考手册均未记录 HAL 函数的作用以及它们应该如何使用。HAL 文档描述了一些常见的用例,其余的应该被视为未记录,即即使一个功能现在看起来可以工作,它也可能随时停止工作。
无论如何,这是我认为应该有效的方法,但我没有 G4 来测试它。我省略了 GPIO 引脚设置,将它们设置为 GPIOA->MODER 中的输出。
1. 确保在 RCC 中启用所有使用的外设(GPIO、TIM、DMA 和 DMAMUX)。


  • RCC->AHB1ENR |= RCC_AHB1ENR_DMAMUX1EN | RCC_AHB1ENR_DMA1EN;
  • RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
  • RCC->APB2ENR |= RCC_APB2ENR_TIM8EN;

2. 设置一个DMA通道从内存数组复制到BSRR。


  • DMA1_Channel2->CMAR = gpio_data;
  • DMA1_Channel2->CPAR = &GPIOA->BSRR;
  • DMA1_Channel2->CNDTR = GPIO_DATA_LENGTH;
  • DMA1_Channel2->CCR =
  •     DMA_CCR_MSIZE_1 | // memory data size 32 bits
  •     DMA_CCR_PSIZE_1 | // peripheral data size 32 bits
  •     DMA_CCR_CIRC    | // circular mode
  •     DMA_CCR_MINC    | // increment memory pointer
  •     DMA_CCR_DIR     | // direction memory to peripheral
  •     DMA_CCR_EN      | // enable channel
  •     0);

3. 将定时器更新 DMA 请求连接到 DMA 通道。


  • DMAMUX1_Channel2->CCR = (DMA_REQUEST_TIM8_UP << DMAMUX_CxCR_DMAREQ_ID_Pos);

4. 设置定时器预分频器、周期、使能 DMA 并启动。


  • TIM8->PSC = 1000 - 1;
  • TIM8->EGR = TIM_EGR_UG; // required to load the prescaler
  • TIM8->ARR = 17000 - 1;
  • TIM8->BDTR = TIM_BDTR_MOE; // required on advanced timers
  • TIM8->SR = 0; // clear status after TIM_EGR_UG
  • TIM8->DIER = TIM_DIER_UDE; // enable DMA on timer update (overflow)
  • TIM8->CR1 = TIM_CR1_CEN; /// start the timer

在每一步之后,检查寄存器值是否实际写入,除了数据表中的重置值外,它们不包含任何内容,这些重置值已根据您编写的内容进行了修改。逐步执行代码并在每一步检查状态寄存器。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分