youkebing 发表于 2023-2-9 17:24:03

请教,stm32g070 能否通过dma把内存数据输出到gpio口

本帖最后由 youkebing 于 2023-2-9 17:25 编辑

前一段时间看到网上有dma输出到gpio的例子,似乎很简单,今天就写了个测试,内存到内存成功,但是内存到GPIOC->BSRR失败!
找一下手册,似乎不行,是我搞错了吗?
从图上看,dma似乎与gpio够不上关系。


SUPER_CRJ 发表于 2023-2-9 19:36:00

BSRR这个寄存器好像只能设置1还是清零。
你试试到:ODR上面。

youkebing 发表于 2023-2-9 19:45:37

SUPER_CRJ 发表于 2023-2-9 19:36
BSRR这个寄存器好像只能设置1还是清零。
你试试到:ODR上面。
(引用自2楼)

试过了,不行,stm32g这个型号

矩阵时间 发表于 2023-2-9 20:40:52

图里头,没有 GPIO 到 DMA 的请求通道,外设那边才有请求通道。GPIO 直接由 M0+ 核 控制

youkebing 发表于 2023-2-9 20:48:51

矩阵时间 发表于 2023-2-9 20:40
图里头,没有 GPIO 到 DMA 的请求通道,外设那边才有请求通道。GPIO 直接由 M0+ 核 控制 ...
(引用自4楼)

看来,gpio不能用dma了

tomzbj 发表于 2023-2-9 20:56:06

当然可以,用m2m模式,就是比较慢
或者用spi, dac, 随便哪个不用的外设的dma触发源,目标地址写成gpio的odr,也一样能工作。
两种方式我都试过。

youkebing 发表于 2023-2-9 21:16:22

tomzbj 发表于 2023-2-9 20:56
当然可以,用m2m模式,就是比较慢
或者用spi, dac, 随便哪个不用的外设的dma触发源,目标地址写成gpio的od ...
(引用自6楼)

你在stm32g这类处理器上测试过吗?我测试内存到内存没问题,但是到gpio不行

tomzbj 发表于 2023-2-9 21:47:53

youkebing 发表于 2023-2-9 21:16
你在stm32g这类处理器上测试过吗?我测试内存到内存没问题,但是到gpio不行 ...
(引用自7楼)

我是用gd32f350试的, 用timer5触发dma写dac, dma的目标地址换成了gpioa.
主频超到240M, timer5设成10分频, 这样得到了一个24M时钟的dds.

stm32g我没试过, 有空试试.

youkebing 发表于 2023-2-9 22:00:06

tomzbj 发表于 2023-2-9 21:47
我是用gd32f350试的, 用timer5触发dma写dac, dma的目标地址换成了gpioa.
主频超到240M, timer5设成10分频 ...
(引用自8楼)

多谢,期待你的好消息

wshtyr 发表于 2023-2-9 22:16:41

GD32F150验证是可以的
定时器捕获和溢出触发DMA,数据从GPIO输入寄存器到内存

cddyy 发表于 2023-2-9 22:17:10

stm32g我试过,不行,哪位大神搞定了帮忙说一声。
估计是为了提高GPIO的操作速度,看框图GPIO是单独拉到内核的,DMA应该无法访问,STM32F系列是可以的。

工程师030 发表于 2023-2-10 09:03:36

楼主可以试试DMA设置定时器触发,因为gpio没有标志位给DMA表示传输完成

youkebing 发表于 2023-2-10 09:43:23

工程师030 发表于 2023-2-10 09:03
楼主可以试试DMA设置定时器触发,因为gpio没有标志位给DMA表示传输完成
(引用自12楼)

我用的是定时器的通道1测试的,是stm32g070 ,你在这个处理器上用过吗?

wshtyr 发表于 2023-2-10 16:31:28

LZ需要控制几个IO?从手册上看,这个系列的mcu把gpio独立出来了,连地址都不是40000000开头的,dma是访问不到gpio的寄存器的
但如果需要控制的io不大于4个,可以尝试利用定时器的输出通道,通过af方式来输出波形

youkebing 发表于 2023-2-10 16:35:57

wshtyr 发表于 2023-2-10 16:31
LZ需要控制几个IO?从手册上看,这个系列的mcu把gpio独立出来了,连地址都不是40000000开头的,dma是访问不 ...
(引用自14楼)

请问怎么通过af控制呢?能否说的详细一点?

wshtyr 发表于 2023-2-10 17:42:32

youkebing 发表于 2023-2-10 16:35
请问怎么通过af控制呢?能否说的详细一点?
(引用自15楼)

GPIO设置成AF模式,映射到定时器的输出通道
定时器开启DMA,将内存的数据送到定时器的捕获/输出模式寄存器CCMR1, CCMR2
在输出模式下,有两种状态,叫强制高和强制低


预先把“强制高”和“强制低”对应的寄存器值存到内存里,使能定时器的UPDATE DMA,内存里的数据就可以写入CCMR寄存器,实现拉高和拉低的效果
这种方式最多可以用DMA控制4个通道

youkebing 发表于 2023-2-10 18:03:49

wshtyr 发表于 2023-2-10 17:42
GPIO设置成AF模式,映射到定时器的输出通道
定时器开启DMA,将内存的数据送到定时器的捕获/输出模式寄存 ...
(引用自16楼)

多谢,我明白您的意思了,我想用dma直接驱动一个小液晶屏,这样可能就不好实现了

rz007 发表于 2023-2-10 18:20:43

chatgpt回复的代码:

#include "stm32g0xx.h"

#define LED_PIN 5
#define LED_PORT GPIOA

uint32_t ledData[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080};

void DMA1_Channel1_IRQHandler(void)
{
if (DMA1->ISR & DMA_ISR_TCIF1)
{
    DMA1->IFCR |= DMA_IFCR_CTCIF1;
    LED_PORT->ODR ^= ledData;
}
}

int main(void)
{
// Enable the peripheral clock for GPIOA
RCC->IOPENR |= RCC_IOPENR_GPIOAEN;

// Configure the LED pin as an output
LED_PORT->MODER = (LED_PORT->MODER & ~(GPIO_MODER_MODE5 << (LED_PIN * 2))) | (GPIO_MODER_MODE5_0 << (LED_PIN * 2));

// Enable the peripheral clock for DMA1
RCC->AHB2ENR |= RCC_AHB2ENR_DMA1EN;

// Configure the DMA
DMA1_Channel1->CPAR = (uint32_t) &(LED_PORT->ODR);
DMA1_Channel1->CMAR = (uint32_t) ledData;
DMA1_Channel1->CNDTR = 8;
DMA1_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_TCIE;

// Enable the DMA channel
DMA1_Channel1->CCR |= DMA_CCR_EN;

// Enable the DMA1 channel 1 interrupt in the NVIC
NVIC_EnableIRQ(DMA1_Channel1_IRQn);

while (1)
{
    // Wait for the transfer to complete
}
}

youkebing 发表于 2023-2-10 19:28:50

rz007 发表于 2023-2-10 18:20
chatgpt回复的代码:

#include "stm32g0xx.h"

(引用自18楼)

这个代码估计不行,ai都这么牛叉了吗?
页: [1]
查看完整版本: 请教,stm32g070 能否通过dma把内存数据输出到gpio口