GD32F4xx系列单片机-串口配合DMA的使用

devtools/2025/3/15 8:37:13/

将初始化、DMA 配置和数据发送/接收部分分成三个函数。

代码:

1. 初始化函数(UartxInit)

该函数用于初始化串口相关硬件设置(GPIO、USART 和 DMA)。

void UartxInit(uarttypedefenum com){    /* 使能GPIO时钟 */     rcuperiphclockenable(COMGPIOCLK[com]);/* 使能USART时钟 */rcuperiphclockenable(COMCLK[com]);    
/* 配置TX和RX引脚为USART功能 */    gpioafset(COMGPIOPORT[com], COMAF[com], COMTXPIN[com]); // 连接TX引脚    gpioafset(COMGPIOPORT[com], COMAF[com], COMRXPIN[com]); // 连接RX引脚    
/* 配置TX引脚为推挽输出,设置50MHz速度 */     gpiomodeset(COMGPIOPORT[com], GPIOMODEAF, GPIOPUPDPULLUP, COMTXPIN[com]);    gpiooutputoptionsset(COMGPIOPORT[com], GPIOOTYPEPP, GPIOOSPEED50MHZ, COMTXPIN[com]);    
/* 配置RX引脚为推挽输入,设置50MHz速度 */    gpiomodeset(COMGPIOPORT[com], GPIOMODEAF, GPIOPUPDPULLUP, COMRXPIN[com]);    gpiooutputoptionsset(COMGPIOPORT[com],GPIOOTYPEPP, GPIOOSPEED50MHZ, COMRXPIN[com]);    /* 配置USART */    usartdeinit(COMNUM[com]);    usartbaudrateset(COMNUM[com],COMBUADRATE[com]);    usartreceiveconfig(COMNUM[com],USARTRECEIVEENABLE);    usarttransmitconfig(COMNUM[com],USARTTRANSMITENABLE);    usartenable(COMNUM[com]);    /* 配置USART的DMA */    USARTxDMATxInit(COMNUM[com]);    /* 使能USART接收中断 */    usartinterruptenable(COMNUM[com],USARTINTRBNE);    /* 配置NVIC中断 */    nvicirqenable(COMIRQ[com],        COMNVICIRQPRE[com], COMNVICIRQSUB[com]);
}

配置解释:

1.GPIO 配置:设置 TX 和 RX 引脚的功能为 USART,并设置为推挽模式,以保证正确的信号传输。

2.USART 配置:设置波特率和启用发送和接收功能。

3.DMA 配置:启用 USART 的 DMA 功能。

4.中断配置:使能 USART 的接收中断,以便接收数据。

2. DMA 配置函数(UartxDmaConfig)

该函数用于配置 DMA 以支持数据的发送。

void UartxDmaConfig(uarttypedefenum com, uint32_t *data, uint16_t len)
{    
dmasingledataparameterstruct dmainitstruct;    /* 使能DMA时钟 */    
rcuperiphclockenable(RCUDMA1);    /* 反初始化DMA通道 */    
dmadeinit(DMA0, DMACH1);    /* 配置DMA传输参数 */    
dmainitstruct.direction = DMAMEMORYTOPERIPH; // 从内存到外设    
dmainitstruct.memory0addr = (uint32_t)data; // 内存地址    
dmainitstruct.memoryinc = DMAMEMORYINCREASEENABLE; // 启用内存地址递增    
dmainitstruct.periphmemorywidth = DMAPERIPHWIDTH8BIT; // 外设宽度:8位    
dmainitstruct.number = len; // 传输的数据长度    
dmainitstruct.periphaddr = UART6DATAADDRESS; // 外设地址(UART6数据寄存器地址)    
dmainitstruct.periphinc = DMAPERIPHINCREASEDISABLE; // 禁用外设地址递增    
dmainitstruct.priority = DMAPRIORITYULTRAHIGH; // 高优先级    /* 初始化DMA传输模式 */    
dmasingledatamodeinit(DMA0, DMACH1, &dmainitstruct);    /* 配置DMA模式,禁用循环模式 */    
dmacirculationdisable(DMA0, DMACH1);    /* 配置DMA通道外设选择 */    
dmachannelsubperipheralselect(DMA0, DMACH1, DMASUBPERI5);    /* 启用DMA传输 */    
usartdmatransmitconfig(UART6, USARTDENTENABLE);    
dmachannelenable(DMA0, DMACH1);
}

配置解释:

5.DMA 通道配置:配置 DMA 通道参数,设置内存地址、外设地址以及数据传输方向。

6.优先级配置:为 DMA 传输设置超高优先级。

7.DMA 启动:启用 DMA 通道和 USART 的 DMA 发送功能。

3. 数据发送函数(UartxSendData)

该函数用于发送数据并等待发送完成。

int UartxSendData(uarttypedefenum com, uint32_t *data, uint16_t len)
{    
/* 清除USART标志,确保没有之前的传输干扰 */    
usart_flag_clear(COMNUM[com], USART_FLAG_TC);    /* 禁用DMA通道 */    
dma_channel_disable(DMA0, DMACH1);    /* 清除DMA标志 */    
dma_flag_clear(DMA0, DMA_CH1, DMA_FLAG_FTF);    /* 配置DMA传输地址 */    
dma_memory_address_config(DMA0, DMA_CH1, (uint32_t)data);    /* 配置DMA传输的字节数 */    
dma_transfer_number_config(DMA0, DMA_CH1, len);    /* 启动DMA通道 */    
dma_channel_enable(DMA0, DMA_CH1);    /* 启用USART的DMA传输功能 */    
usart_dma_transmit_config(COMNUM[com], USART_DENT_ENABLE);    /* 等待DMA完成数据传输 */    while (RESET == dma_flag_get(DMA0, DMA_CH1, DMA_INTF_FTFIF)) {}    
return 0; // 传输完成
}

配置解释:

8.DMA 配置:清除任何以前的传输标志,重新配置 DMA 传输参数。

9.DMA 启动:启用 DMA 通道并启动数据传输。

10.等待传输完成:使用 DMA 完成传输的标志来阻塞直到数据传输完成。

4. 数据接收函数(UartxReceiveData)

该函数用于通过 USART 接收数据。

int UartxReceiveData(uarttypedefenum com, uint32_t *buffer, uint16_t len)
{    
/* 清除接收标志 */
usart_flag_clear(COMNUM[com], USART_FLAG_RXNE);    /* 启动DMA接收 */dma_channel_disable(DMA0, DMACH1); // 禁用DMA通道dma_flag_clear(DMA0, DMA_CH1, DMA_FLAG_FTF); // 清除DMA标志dma_memory_address_config(DMA0, DMA_CH1, (uint32_t)buffer); // 配置接收缓冲区地址dma_transfer_number_config(DMA0, DMA_CH1, len); // 配置接收数据长度dma_channel_enable(DMA0, DMA_CH1); // 启动DMA接收通道/* 启用USART DMA接收功能 */    usart_dmarx_enable(COMNUM[com]);    /* 等待接收完成 */while (RESET == dma_flag_get(DMA0, DMA_CH1, DMA_INTF_FTFIF)) {}    return 0; // 接收完成
}

配置解释:

11.DMA 接收配置:配置接收缓冲区并启动 DMA 接收通道。

12.等待接收完成:通过 DMA 完成标志来检测数据接收是否完成。

总结

代码通过将初始化、DMA 配置、数据发送和接收拆分成了多个函数,使代码结构更加清晰,模块化程度更高。

每个函数负责不同的任务,可以在实际应用中方便地进行维护和扩展。


http://www.ppmy.cn/devtools/167247.html

相关文章

Java vs Go:SaaS 系统架构选型解析与最佳实践

在构建 SaaS(Software as a Service)系统时,选用合适的技术栈至关重要。Java 和 Go 是当今最受欢迎的后端开发语言之一,各自有其优势和适用场景。那么,SaaS 系统开发应该选择 Java 还是 Go?本文将从多个维度…

【SpringMVC】入门版

1.基本概念 1.1三层架构 三层架构也就是我们常说的b/s架构中的表现层,业务层和持久层,每层都各司其职,下面来分别讲解这三层的作用。 表现层: 也就是我们常说的web层。它负责接收客户端的请求,向客户端响应结果,通…

华为OD机试-篮球游戏(Java 2024 D卷 100分)

题目描述 幼儿园里有一个放倒的圆桶,它是一个线性结构 ( Q ),允许在桶的右边将篮球放入,可以在桶的左边和右边将篮球取出。每个篮球有单独的编号,老师可以连续放入一个或多个篮球,小朋友可以在桶左边或右边将篮球取出,当桶里只有一个篮球的情况下,必须从左边取出。 输…

爬虫案例十四js逆向中国五矿

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、网站分析二、代码 前言 提示:这里可以添加本文要记录的大概内容: js逆向中国五矿 提示:以下是本篇文章正文内容&#…

UG的一些操作步骤(自用笔记2)

目录 1.曲面操作和编辑 2.工程图 3.尺寸标注 4.钣金基本特征 5.钣金高级特征 6.建立有限元模型 7.模型编辑与后处理 8.机构分析基础 9.模型准备与运动分析 10.运动分析总结 1.曲面操作和编辑 1.曲面操作: 偏置曲面:菜单——插入——偏置/缩放…

‌Visual Studio Code(VS Code)支持的编程语言

‌JavaScript‌:VS Code 原生支持 JavaScript,提供语法高亮、代码折叠、自动补全等功能。推荐使用ESLint和Prettier进行代码格式化和错误检查‌。 ‌TypeScript‌:作为 JavaScript 的超集,TypeScript 在 VS Code 中也得到原生支持…

python多种数据类型输出为Excel文件

python中的列表、元组、字典、集合有时包含大量的数据,而这样的变量在主流编辑器PyCharm中并不能像MATLAB那样直接可视化显示出来亦或直接打印、复制粘贴。如下图是一张图片的像素点数据: 因此我们需要将这些变量的数值输出到Excel中,方便后续…

Python蓝桥杯

蓝桥杯是一项面向全国青少年的编程竞赛,Python是其中的参赛语言之一。以下是关于Python蓝桥杯的一些信息: 比赛内容 - 基础编程知识:包括Python语言的基础语法、数据结构(如列表、字典、元组等)、控制流&#xff0…