发新帖我要提问
12
返回列表
打印

GD32F450如何实现串口的DMA方式发送数据?

[复制链接]
楼主: matrix12
手机看帖
扫描二维码
随时随地手机跟帖
21
sdlls| | 2024-5-7 15:29 | 只看该作者 回帖奖励 |倒序浏览
当DMA传输完成时,会产生一个中断信号。您需要编写一个中断服务程序来处理这个信号,例如更新发送计数器、清空DMA缓冲区等。

使用特权

评论回复
22
averyleigh| | 2024-5-7 18:35 | 只看该作者
需要配置DMA通道,这包括设置数据方向(通常是从内存到串口)、数据宽度(如8位、16位或32位)、传输模式(如正常模式或循环模式)等参数。

使用特权

评论回复
23
benjaminka| | 2024-5-7 21:45 | 只看该作者
如果需要,可以设置完成传输后的中断,以便在数据传输完成后执行特定的操作。

使用特权

评论回复
24
chenqianqian| | 2024-5-8 08:17 | 只看该作者
设置DMA通道,缓冲数据长度。

使用特权

评论回复
25
minzisc| | 2024-5-8 13:28 | 只看该作者
传输完成后,可以通过DMA_Cmd()函数关闭DMA通道以节省资源。

使用特权

评论回复
26
lzbf| | 2024-5-8 16:41 | 只看该作者
参考GD32F450的官方开发文档和库函数手册

使用特权

评论回复
27
geraldbetty| | 2024-5-8 19:50 | 只看该作者
为了使用DMA发送数据,你需要配置一个DMA缓冲区。这个缓冲区通常是一个内存区域,用于存储要发送的数据。你需要指定这个缓冲区的起始地址和长度。

使用特权

评论回复
28
pmp| | 2024-5-8 22:55 | 只看该作者
所用串口发送对应的DMA通道,例如串口2对应DMA0的CH1。在配置DMA通道时,需要注意使能相应的时钟。

使用特权

评论回复
29
digit0| | 2024-5-8 23:06 | 只看该作者
你可参考相关的示例代码,了解如何实施串行端口数据传输的 dma 模式。

使用特权

评论回复
30
mikewalpole| | 2024-5-9 11:56 | 只看该作者
#include "gd32f4xx.h"
#include "gd32f450z_eval.h"

void dma_init(void);
void usart_init(void);

uint8_t send_data[] = "Hello, DMA!";

int main(void)
{
    dma_init();
    usart_init();

    // 启动DMA传输
    dma_channel_enable(DMA_CH1);

    while (1)
    {
        // 等待DMA传输完成
        while (dma_flag_get(DMA_CH1, DMA_FLAG_FTF) == RESET);

        // 重新启动DMA传输
        dma_channel_enable(DMA_CH1);
    }
}

void dma_init(void)
{
    // 使能DMA时钟
    rcu_periph_clock_enable(RCU_DMA);

    // 配置DMA通道1
    dma_deinit(DMA_CH1);
    dma_periph_address_config(DMA_CH1, (uint32_t)&USART_DATA(USART0));
    dma_memory_address_config(DMA_CH1, (uint32_t)send_data);
    dma_transfer_number_config(DMA_CH1, sizeof(send_data) - 1);
    dma_channel_direction_config(DMA_CH1, DMA_MEMORY_TO_PERIPHERAL);
    dma_memory_width_config(DMA_CH1, DMA_MEMORY_WIDTH_8BIT);
    dma_periph_width_config(DMA_CH1, DMA_PERIPHERAL_WIDTH_8BIT);
    dma_priority_config(DMA_CH1, DMA_PRIORITY_ULTRA_HIGH);
    dma_transfer_mode_config(DMA_CH1, DMA_PERIPHERAL_TO_MEMORY);
    dma_memory_to_memory_disable(DMA_CH1);
}

void usart_init(void)
{
    // 使能GPIOA和USART0时钟
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);

    // 配置GPIOA9和GPIOA10为USART0的TX和RX引脚
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9 | GPIO_PIN_10);

    // 配置USART0
    usart_deinit(USART0);
    usart_baudrate_set(USART0, 115200);
    usart_word_length_set(USART0, USART_WL_8BIT);
    usart_stop_bit_set(USART0, USART_STB_1BIT);
    usart_parity_config(USART0, USART_PM_NONE);
    usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
    usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_enable(USART0);

    // 使能USART0的DMA发送功能
    usart_dma_transmit_config(USART0, USART_DENT_ENABLE);
}

使用特权

评论回复
31
primojones| | 2024-5-9 15:07 | 只看该作者
使用DMA发送数据的函数,该函数将数据放入DMA缓冲区,并启动DMA传输。

使用特权

评论回复
32
hilahope| | 2024-5-9 18:15 | 只看该作者
使能串口时钟:通过RCC_APBxPeriphClockCmd()函数开启串口相关的时钟。
使能DMA时钟:通过RCC_AHBPeriphClockCmd()函数开启DMA时钟。

使用特权

评论回复
33
朝生| | 2024-5-10 07:10 | 只看该作者
您可以参考相关的示例代码来了解如何实现串口数据传输 dma 模式。

使用特权

评论回复
34
AIsignel| | 2024-5-10 23:47 | 只看该作者
您可以参考相关的示例代码来学习如何实现串行数据传输、 dma、模式。

使用特权

评论回复
35
埃娃| | 2024-5-15 22:19 | 只看该作者
照着例程写一下呗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则