打印

使用DMA从USART接收数据

[复制链接]
40|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
铁血丹心LLLL|  楼主 | 2025-2-22 16:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一个常见的DMA应用场景是从USART接收数据,并将其存储到内存中。

通过DMA,我们可以实现USART接收数据的高效传输,而不需要CPU干预。

以下是具体的应用实例:

配置USART和DMA
初始化USART:

配置USART为接收模式。
启用USART中断和DMA请求。
配置DMA:

配置DMA通道,用于将接收到的USART数据传输到内存中。
配置DMA的源地址为USART的数据寄存器,目标地址为接收缓冲区。
代码实现
以下是一个从USART接收数据并使用DMA存储到内存的实例代码:
c
#include "gd32e230.h"

#define BUFFER_SIZE 100
uint8_t rx_buffer[BUFFER_SIZE];  // 数据接收缓冲区

// 配置USART1
void usart_config(void) {
    rcu_periph_clock_enable(RCPU_USART1);    // 启用USART1时钟
    rcu_periph_clock_enable(RCPU_GPIOA);     // 启用GPIOA时钟

    // 配置PA9为USART1的TX引脚,PA10为USART1的RX引脚
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);  // TX
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);  // RX

    // 配置USART1,波特率9600,8数据位,1停止位,无校验
    usart_deinit(USART1);
    usart_init(USART1, 9600, USART_WL_8BIT, USART_STB_1BIT, USART_PERR_NOPARITY);

    // 启用USART1接收DMA请求
    usart_dma_enable(USART1, USART_DMA_RECEIVE);
    usart_enable(USART1);
}

// 配置DMA
void dma_config(void) {
    // 启用DMA时钟
    rcu_periph_clock_enable(RCPU_DMA);

    // 配置DMA通道:将USART1的数据接收寄存器传输到rx_buffer
    dma_channel_struct_init(&dma_init_struct);
    dma_init_struct.peripheral_address = (uint32_t)&USART_DATA(USART1);  // USART1数据寄存器地址
    dma_init_struct.memory_address = (uint32_t)rx_buffer;  // 数据存储到rx_buffer
    dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;  // 外设到内存
    dma_init_struct.number_of_data = BUFFER_SIZE;  // 传输100个字节
    dma_init_struct.priority = DMA_PRIORITY_HIGH;  // 高优先级
    dma_channel_init(DMA1, DMA_CHANNEL_4, &dma_init_struct);  // 配置DMA1通道4(USART1接收)

    // 启用DMA通道
    dma_channel_enable(DMA1, DMA_CHANNEL_4);
}

void dma_transfer_complete_irq(void) {
    // 处理DMA完成中断,数据接收完成
    if (dma_flag_get(DMA1, DMA_FLAG_TC4)) {
        // 处理接收到的数据,例如打印接收到的数据
        for (int i = 0; i < BUFFER_SIZE; i++) {
            printf("Received data[%d]: %c\n", i, rx_buffer[i]);
        }

        // 清除DMA传输完成标志
        dma_flag_clear(DMA1, DMA_FLAG_TC4);
    }
}

int main(void) {
    usart_config();  // 配置USART1
    dma_config();    // 配置DMA

    while (1) {
        // CPU可以继续执行其他任务,DMA接收数据时,CPU可以不干预
        // 当DMA接收完成时,通过中断或标志通知CPU
    }
}
说明
USART配置:通过usart_init()函数配置USART的波特率、数据位、停止位和校验方式。usart_dma_enable()函数启用USART的DMA接收请求。
DMA配置:通过dma_channel_init()函数配置DMA通道,指定源地址(USART的接收数据寄存器)和目标地址(接收缓冲区rx_buffer)。
DMA中断:在DMA传输完成后,可以启用DMA中断,通知CPU数据接收已完成。在dma_transfer_complete_irq()中断服务函数中,我们处理接收到的数据。
DMA传输的优势
自动化传输:DMA自动从USART接收数据并存储到内存,无需CPU的干预。
提高效率:数据传输速度比CPU轮询要快得多。
节省CPU资源:在DMA完成数据传输时,CPU可以处理其他任务,只有在传输完成时才需要处理相关数据。

使用特权

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

本版积分规则

72

主题

496

帖子

1

粉丝