打印
[研电赛技术支持]

GD32串口DMA与空闲中断串口数据进行处理

[复制链接]
1115|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2023-10-19 11:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
DMA 全称Direct Memory Access,即直接存储器访问。

DMA传输将数据从一个地址空间复制到另一个地址空间。当CPU初始化这个传输动作,传输动作本身是由DMA控制器来实现和完成的。

GD32F450有两个DMA控制器(DMA2只存在于大容量产品中),DMA1和DMA2都有8个通道,每个通道专门用来管理来自于一个或者多个外设对存储器的访问请求。还有一个仲裁器来协调各个DMA请求的优先权。

串口DMA作用是减轻CPU负担开销。

GD32串口空闲中断是指当串口接收缓冲区中没有数据时,会触发空闲中断。在空闲中断中,我们可以将接收数据搬运至接收二级缓存区中。使用空闲中断可以在保证数据完整性的同时提高串口接收数据的效率。

1.H文件

#ifndef _MODEL_CONSOLE_INIT_H
#define _MODEL_CONSOLE_INIT_H

#include "gd32f4xx.h"

#define MAX_SIZE_OF_USART0_RX_BUFFER 512 // 接收缓存区大小
#define MAX_SIZE_OF_USART0_TX_BUFFER 512 // 接收缓存区大小

extern unsigned char usart0_rx_DataBuf[MAX_SIZE_OF_USART0_RX_BUFFER];

void model_console_init(void);
void model_console_init_dma_config(void);
void model_console_Send_Buff(unsigned char* pdata, unsigned short usLen);
int fputc(int ch, FILE *f);
#endif
2.C文件

#include "main.h"
#include "model_console_init.h"
#include "model_console_buff.h"
#include "model_common_frame.h"
#include "gd32f4xx_dma.h"
#include "gd32f4xx_usart.h"
#include "gd32f4xx_rcu.h"
#include "gd32f4xx_gpio.h"

unsigned char usart0_rx_DataBuf[MAX_SIZE_OF_USART0_RX_BUFFER] = {0};

#define BSP_USART_TX_RCU        RCU_GPIOA
#define BSP_USART_RX_RCU        RCU_GPIOA
#define BSP_USART_RCU                RCU_USART0

#define BSP_USART_TX_PORT        GPIOA
#define BSP_USART_RX_PORT         GPIOA
#define BSP_USART_AF                 GPIO_AF_7
#define BSP_USART_TX_PIN        GPIO_PIN_9
#define BSP_USART_RX_PIN        GPIO_PIN_10

#define BSP_USART                        USART0
#define BSP_USART_IRQ                USART0_IRQn
#define BSP_USART_BAUD                115200
static void model_console_init_usart_gpio_config(void)
{
  /* 开启时钟 */
        rcu_periph_clock_enable(BSP_USART_TX_RCU);
        rcu_periph_clock_enable(BSP_USART_RX_RCU);
        rcu_periph_clock_enable(BSP_USART_RCU);
       
        /* 配置GPIO复用功能 */
          gpio_af_set(BSP_USART_TX_PORT,BSP_USART_AF,BSP_USART_TX_PIN);       
        gpio_af_set(BSP_USART_RX_PORT,BSP_USART_AF,BSP_USART_RX_PIN);       
       
        /* 配置GPIO的模式 */
        /* 配置TX为复用模式 上拉模式 */
        gpio_mode_set(BSP_USART_TX_PORT,GPIO_MODE_AF,GPIO_PUPD_PULLUP,BSP_USART_TX_PIN);
        gpio_mode_set(BSP_USART_RX_PORT, GPIO_MODE_AF,GPIO_PUPD_PULLUP,BSP_USART_RX_PIN);
       
        /* 配置TX为推挽输出 50MHZ */
        gpio_output_options_set(BSP_USART_TX_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,BSP_USART_TX_PIN);
        gpio_output_options_set(BSP_USART_RX_PORT,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, BSP_USART_RX_PIN);

        /* 配置串口的参数 */
        usart_deinit(BSP_USART);
        usart_baudrate_set(BSP_USART,BSP_USART_BAUD);
        usart_parity_config(BSP_USART,USART_PM_NONE);
        usart_word_length_set(BSP_USART,USART_WL_8BIT);
        usart_stop_bit_set(BSP_USART,USART_STB_1BIT);

          /* 使能串口 */
        usart_enable(BSP_USART);
        usart_transmit_config(BSP_USART,USART_TRANSMIT_ENABLE);
        usart_receive_config(BSP_USART,USART_RECEIVE_ENABLE);
       
        nvic_irq_enable(BSP_USART_IRQ, 2, 2);
       
        // usart_interrupt_enable(BSP_USART,USART_INT_RBNE);
        usart_interrupt_enable(BSP_USART,USART_INT_IDLE);
}

#define BSP_DMA_RCU                                RCU_DMA1
#define BSP_DMA                                        DMA1
#define BSP_DMA_CH                                DMA_CH2
#define BSP_DMA_CH_IRQ                        DMA1_Channel2_IRQn
#define BSP_DMA_CH_IRQ_HANDLER        DMA1_Channel2_IRQHandler
void model_console_init_dma_config(void)
{
        dma_single_data_parameter_struct dma_init_struct;
        rcu_periph_clock_enable(BSP_DMA_RCU);

        dma_interrupt_flag_clear(BSP_DMA, BSP_DMA_CH, DMA_INTC_FEEIFC|DMA_INTC_SDEIFC|DMA_INTC_TAEIFC|DMA_INTC_HTFIFC|DMA_INTC_FTFIFC);//中断标志位清除       
         
        dma_deinit(BSP_DMA,BSP_DMA_CH);
       
        dma_init_struct.periph_addr = (uint32_t)&USART_DATA(BSP_USART);                        
        dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;                          
        dma_init_struct.memory0_addr = (uint32_t)usart0_rx_DataBuf;                        
        dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;                          
        dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;                  
        dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE;                     
        dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;                           
        dma_init_struct.number = MAX_SIZE_OF_USART0_RX_BUFFER;                              
        dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;  
       
         dma_single_data_mode_init(BSP_DMA,BSP_DMA_CH,&dma_init_struct);
       
         dma_channel_subperipheral_select(BSP_DMA,BSP_DMA_CH,DMA_SUBPERI4);
       
         dma_channel_enable(BSP_DMA,BSP_DMA_CH);
       
        //  dma_interrupt_enable(BSP_DMA,BSP_DMA_CH,DMA_CHXCTL_FTFIE);
        //  nvic_irq_enable(BSP_DMA_CH_IRQ, 2, 1);
         
         usart_dma_receive_config(BSP_USART,USART_DENR_ENABLE);
}

void model_console_init(void)
{
        model_console_init_usart_gpio_config();
        model_console_init_dma_config();
}

void model_console_Send_Buff(unsigned char* pdata, unsigned short usLen)        //串口输出字符串
{
    for(unsigned int i=0;i<usLen;i++)
    {
                usart_data_transmit(BSP_USART, pdata);
                while (RESET == usart_flag_get(BSP_USART, USART_FLAG_TBE));
    }
}

int fputc(int ch, FILE *f)
{
        usart_data_transmit(BSP_USART, (uint8_t)ch);
        while (RESET == usart_flag_get(BSP_USART, USART_FLAG_TBE));
        return ch;
}



————————————————
版权声明:本文为CSDN博主「嵌入式小宁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_53592457/article/details/132758705

使用特权

评论回复
沙发
lajfda001| | 2023-10-19 16:07 | 只看该作者
DMA会影响到中断吗?

使用特权

评论回复
板凳
tpgf|  楼主 | 2023-11-3 09:25 | 只看该作者
lajfda001 发表于 2023-10-19 16:07
DMA会影响到中断吗?

不会影响到正常的中断的 这个不用担心

使用特权

评论回复
地板
gwsan| | 2023-11-3 10:00 | 只看该作者
这种相当于利用了时间碎片来处理问题

使用特权

评论回复
5
tfqi| | 2023-11-3 21:31 | 只看该作者
这种处理问题的方式显然是非常紧凑的

使用特权

评论回复
6
zljiu| | 2023-11-3 22:02 | 只看该作者
一个dma只能控制一个功能吗

使用特权

评论回复
7
aoyi| | 2023-11-3 22:41 | 只看该作者
所有的芯片都可以通过这种方式进行处理吧

使用特权

评论回复
8
nawu| | 2023-11-3 23:25 | 只看该作者
但是如果数据较多 这样处理是不是就不太够用了啊

使用特权

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

本版积分规则

1360

主题

13960

帖子

8

粉丝