GD32F4xx系列的串口收发DMA+空闲中断基础配置:(这里主要是以DMA+空闲中断为例)
原理就不赘述了,网上资料很多,这里直接进行配置和测试。

1,首先添加GD32F4xx的dma外设库函数文件到工程中。

2,新建一个uart_dma.c文件并添加到工程中。

3,配置串口的DMA传输。
这里以USART1为例进行配置,配置不同的串口需要通过GD32F4xx用户手册找到对应的DMA编号和通道


代码编写:

uart_dma.c文件//通过上面的表格可以发现USART1  Tx对应DMA0 的通道6,rx对应DMA0的通道5,因此在进行DMA配置的时候可以按照表格进行配置
uint8_t g_send_data[256];//发送数据
uint8_t g_recv_data[256];//接收数据int32_t uart_dma_init(void)
{usart_deinit(USART1);usart_disable(USART1);rcu_periph_clock_enable(RCU_GPIOA);rcu_periph_clock_enable(RCU_USART1);gpio_af_set(GPIOA,GPIO_AF_7,GPIO_PIN_2|GPIO_PIN_3);gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2|GPIO_PIN_3);gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2|GPIO_PIN_3);nvic_irq_enable(USART1_IRQn,5,0);usart_baudrate_set(USART1,9600);usart_parity_config(USART1,USART_PM_NONE);usart_word_length_set(USART1,USART_WL_8BIT);usart_stop_bit_set(USART1,USART_STB_1BIT);usart_hardware_flow_coherence_config(USART1,USART_HCM_NONE);usart_data_first_config(USART1,USART_MSBF_LSB);usart_enable(USART1);usart_transmit_config(USART1,USART_TRANSMIT_ENABLE);usart_receive_config(USART1,USART_RECEIVE_ENABLE);usart_dma_transmit_config(USART1, USART_DENT_ENABLE);//打开串口DMA发送usart_dma_receive_config(USART1, USART_DENR_ENABLE);//打开串口DMA接收usart_flag_clear(USART1, USART_FLAG_TC);usart_interrupt_enable(USART1,USART_INT_IDLE);//使用串口空闲中断return 0;
}int32_t usart_dma_tx_init(void)
{dma_single_data_parameter_struct dma_init_struct;/* enable DMA0 */rcu_periph_clock_enable(RCU_DMA0);/* deinitialize DMA channel6(USART1 tx) */dma_deinit(DMA0, DMA_CH6);//Tx对应DMA0 通道6dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;dma_init_struct.memory0_addr = (uint32_t)g_send_data;dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;dma_init_struct.number = sizeof(g_send_data);dma_init_struct.periph_addr = (uint32_t)(&USART_DATA(USART1));dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;dma_single_data_mode_init(DMA0, DMA_CH6, &dma_init_struct);dma_channel_subperipheral_select(DMA0, DMA_CH6, DMA_SUBPERI4);//configure DMA mode dma_circulation_disable(DMA0, DMA_CH6);return 0;
}int32_t usart_dma_rx_init(void)
{dma_single_data_parameter_struct dma_parameter;/* enable DMA0 */rcu_periph_clock_enable(RCU_DMA0);/* 接收 dm0 channel5(USART1 rx) */dma_deinit(DMA0, DMA_CH5);//rx对应DMA0通道5dma_parameter.direction = DMA_PERIPH_TO_MEMORY;dma_parameter.periph_addr = (uint32_t)(&USART_DATA(USART1));dma_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;dma_parameter.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;dma_parameter.memory0_addr = (uint32_t)g_recv_data;dma_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;dma_parameter.number = sizeof(g_recv_data);dma_parameter.priority = DMA_PRIORITY_ULTRA_HIGH;dma_parameter.circular_mode = DMA_CIRCULAR_MODE_DISABLE;dma_single_data_mode_init(DMA0, DMA_CH5, &dma_parameter);/* configure DMA mode */dma_channel_subperipheral_select(DMA0, DMA_CH5, DMA_SUBPERI4);dma_channel_enable(DMA0, DMA_CH5);return 0;
}/*** @brief  调试信息发送接口* @param  data:调试数据指针;\*          len:调试数据的数据长度* @retval 0或其他错误代码**/
int32_t uart_dma_send(uint8_t *data,uint32_t len)
{usart_flag_clear(USART1, USART_FLAG_TC);dma_channel_disable(DMA0, DMA_CH6);dma_flag_clear(DMA0, DMA_CH6, DMA_FLAG_FTF);dma_memory_address_config(DMA0, DMA_CH6, DMA_MEMORY_0, (uint32_t)data);dma_transfer_number_config(DMA0, DMA_CH6, len);dma_channel_enable(DMA0, DMA_CH6);while (usart_flag_get(USART1, USART_FLAG_TC)!=RESET);return 0;
}int32_t uart_dma_stop(void)
{usart_disable(USART1);return 0;
}gd32f4xx_it.c文件
extern uint32_t g_recv_data[256];void USART1_IRQHandler(void)
{uint32_t recv_len=0;if(usart_interrupt_flag_get(USART1,USART_INT_FLAG_IDLE) != RESET){usart_interrupt_flag_clear(USART1,USART_INT_FLAG_IDLE);USART_STAT0(USART1);USART_DATA(USART1);dma_channel_disable(DMA0, DMA_CH5);recv_len = sizeof(g_recv_data) - dma_transfer_number_get(DMA0, DMA_CH5);if(recv_len != 0 && recv_len < sizeof(g_recv_data)){//memcpy(g_serial_recv_buf,data_buffer,g_recv_positin); ///* 转存数据到待处理数据缓冲区// 重新设置DMA传输 dma_memory_address_config(DMA0, DMA_CH5,(uint32_t)g_recv_data,DMA_MEMORY_0);dma_transfer_number_config(DMA0, DMA_CH5,sizeof(g_recv_data));dma_flag_clear(DMA0, DMA_CH5, DMA_FLAG_FTF);dma_channel_enable(DMA0, DMA_CH5);      ///* 开启DMA传输 }else{memset(g_recv_data,0,sizeof(g_recv_data));}}return ;
}

4,配置完成后,同样我们再main函数中调用初始化并进行串口数据发送

5,连接好串口和MCU,使用串口工具设置波特率9600 和相关配置与MCU串口初始化一致,打开串口工具可以接收到MCU发送过来的数据。

修改发送的数据内容,查看串口助手接收数据也变化成修改后的数据。

串口DMA发送数据正常
6,使用串口工具给MCU发送数据。
使用串口工具发送一个字节hex数据,使用调试模式查看MCU接收到的数据,对比串口发送的数据与MCU接收的数据一致。

使用串口发送多字节数据,查看MCU接收数据是否正确。

串口DMA接收数据正常。

串口发送测试:(这里做一下串口DMA模式连续发送数据所占用MCU时间的测试与之前的中断模式对比);
程序先运行到发送数据之前,当前的系统时钟大约运行7ms 左右

发送完成后当前的系统时间仍然是7ms,串口DMA发送数据是不占用MCU时间的,DMA相当于是二级缓存。所以当发送数据较多的时候使用DMA进行数据传输可以极大的减少MCU的开销。
(这里也要注意DMA发送虽然不占用MCU的开销,但是仍需要发送时间,若DMA数据未发送完成又继续调用DMA发送可能会导致数据丢包,解决办法就是可以设置DMA发送完成中断,在DMA发送完成中断后再进行下一次的DMA发送就可以了这里就没有示例了。)

使用DMA+空闲中断的话可以减少MCU接收数据中断的次数。正常接收中断模式我们每接收一个字节需要进入中断一次,而空闲中断的话接收一串字符只需要进入一次中断(即在串口空闲的时候触发中断)。也可以一定程度的减少MCU的开销。

GD32F4xx串口收发,DMA+空闲中断相关推荐

  1. stm32的rxne和idle中断_STM32 HAL CubeMX 串口IDLE接收空闲中断+DMA

    历程详解 详解包括: 中断原理讲解 例程流程详解 库函数分析详解 对应寄存器介绍 对应函数介绍 对应注释详解 本篇文章提供两种方法: 一种是 :IDLE 接收空闲中断+DMA 一种是: IDLE 接收 ...

  2. STM32应用(七)JY901九轴姿态模块(串口DMA空闲中断和I2C通信)

    文章目录 0.相关基础知识介绍 0.1六轴.九轴传感器有什么区别? 1.JY901模块简介 1.1 产品概述 1.2 性能参数 1.3 实物图和接线 2.软件和使用说明书 3.串口通信JY901 3. ...

  3. STM32-HAL库串口DMA空闲中断的正确使用方式+解析SBUS信号

    STM32-HAL库串口DMA空闲中断的正确使用方式+解析SBUS信号 一. 问题描述 二. 方法一--使用HAL_UART_Receive_DMA 三. 方法二--使用HAL_UARTEx_Rece ...

  4. STM32 FreeRTOS USART DMA空闲中断和消息队列的使用

    (后文有修改) 一.思路 USART+DMA空闲中断发生后,将接收到的DMA消息用消息队列发出去xQueueSendToFrontFromISR,FreeRTOS创建一个独立的任务一直等待接受消息队列 ...

  5. STM32L476 DMA空闲中断使用问题

    项目场景: 使用STM32L476最小核心板与4G模块通信 问题描述: 使用了HAL DMA空闲中断的方式与模块通信.测试中发现,串口会时不时的接收数据失败,重新初始化串口,又可以使用了. 这个是串口 ...

  6. stm32的串口DMA空闲中断接收不等长数据,stm32F1的usart1-DMA-IDLE收发

    stm32的DMA收发原理,和stm32F4 + USART2 +DMA +IDLE使用,见另一篇:https://blog.csdn.net/Mark_md/article/details/1072 ...

  7. stm32的串口DMA空闲中断接收不等长数据,stm32F4的usart2-DMA-IDLE收发

    1. 串口为什么要使用DMA?好处? 提高系统实时性:stm32单片机的串口没有FIFO,使用字节中断的方式去接收,会频繁进入中断,影响系统实时性.好在stm32的串口可以级联DMA使用,在大数据量连 ...

  8. STM32 HAL CubeMX 串口IDLE接收空闲中断+DMA

    关于DMA原理部分讲解,及CubeMx配置部分,请参考该文章 [STM32]HAL库 STM32CubeMX教程十一-DMA (串口DMA发送接收) 本篇文章我们仅针对例程进行详解剖析 历程详解 详解 ...

  9. 基于STM32F407标准库串口DMA+空闲中断

    核心板:STM32F407 实验目的:通过DMA接收串口发来的数据,并且利用串口空闲中断在将这些数据发送至串口助手. 在通常我们使用串口接收数据时,会使能串口接收中断,并在每次接收到数据后会进入中断将 ...

最新文章

  1. python项目实例初学者-python 初学者必备14张思维导图
  2. idea run和debug都是灰色的,没法点怎么解决
  3. gcc编译流程及中间表示层RTL的探索
  4. C++学习之路 | PTA乙级—— 1038 统计同成绩学生 (20 分)(精简)
  5. arduino使用oled代码_【惊不?】Arduino改造古董卡西欧计算器为作弊神器
  6. leetcode - 101. 对称二叉树
  7. python编码转换规范_Python转载[编码规范]
  8. 聊聊 scala 的模式匹配 1
  9. VMware vSphere 6 序列号大全
  10. 如何用Python将普通视频变成动漫视频
  11. Edge安装插件错误(download interrupted)解决办法
  12. 关于使用Git pull出现冲突“error: Your local changes to the following files would be overwritten by merge”解决方案
  13. 《GPU编程与CG语言之阳春白雪下里巴人》 读书笔记1
  14. 在淘宝上遭遇诈骗卖家
  15. 分享 | 带来全新交互体验的『支付宝AR』技术大解密
  16. Matlab2018a崩溃解决的办法No sandbox or build area path
  17. 手机计算机文档如何发到手机上,如何把电脑上的文件发送到手机上?
  18. Python3 爬虫模板
  19. python之获取本机ip
  20. mysql中模型的作用是什么_BIM模型包括什么信息功能?BIM模型有哪些功能应用

热门文章

  1. 眼袋、眼袋、眼袋!眼袋一直有~~~~ 肿么办啊
  2. 硬盘格式化后怎么恢复文件
  3. 【DeprecationWarning: BICUBIC is deprecated and will be removed in Pillow 10 (2023-07-01).的解决方案】
  4. 「维基解密」:西游记死亡人数
  5. 金蝶云苍穹集成,苍穹到eas审核反审核
  6. 【毛球科技】食品供应链的可持续性挑战
  7. 修复 Android 系统问题的 9 款最佳 Android 手机维修软件和应用
  8. 【Unity3D插件】AVPro Video插件分享《视频播放插件》
  9. 三星 v版系统更新无法连接到服务器,《异能勇者》万人新服紧急新开 更新最新版领取新服礼遇...
  10. LightOJ 1336 Sigma Function