小熊派gd32f303学习之旅(4)—使用DMA实现串口打印

一、前言

在上一篇文章(串口打印第一个Hello world程序)我们使用重定义fputc函数的方式实现了串口打印,但是这种方式本质上是在循环输出字符,比较浪费CPU资源。
解决这个问题的方法就是使用DMA进行发送。
通过串口gd32f30x的用户手册,可以看到,uart0的发送使用的的DMA0的通道3

二、添加DMA驱动

在之前的uart0_init()函数中添加DMA的初始化,如下:

 /* 定义一个DMA配置结构体 */dma_parameter_struct dma_init_struct;/* 使能 DMA 时钟 */rcu_periph_clock_enable(RCU_DMA0);/* 初始化 DMA0 通道3 */dma_deinit(DMA0, DMA_CH3);dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;      /* 存储器到外设方向 */dma_init_struct.memory_addr = (uint32_t)UART0_TX_BUF;        /* 存储器基地址 */dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;   /* 存储器地址自增 */dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;     /* 存储器位宽为8位 */dma_init_struct.number = UART0_TX_LEN;                       /* 传输数据个数 */dma_init_struct.periph_addr = ((uint32_t)0x40013804);      /* 外设基地址,即USART数据寄存器地址 */dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;  /* 外设地址固定不变 */dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;    /* 外设数据位宽为8位 */dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;         /* 软件优先级为极高*/dma_init(DMA0, DMA_CH3, &dma_init_struct);/* DMA循环模式配置,不使用循环模式 */dma_circulation_disable(DMA0, DMA_CH3);/* DMA存储器到存储器模式模式配置,不使用存储器到存储器模式*/dma_memory_to_memory_disable(DMA0, DMA_CH3);/* USART DMA 发送使能 */usart_dma_transmit_config(USART0, USART_DENT_ENABLE);/* DMA0 通道3 中断优先级设置并使能 */nvic_irq_enable(DMA0_Channel3_IRQn, 0, 0);/* 使能 DMA0 通道3 传输完成、传输错误中断 */dma_interrupt_enable(DMA0, DMA_CH3, DMA_INT_FTF|DMA_INT_ERR);/* 使能 DMA0 通道3 */dma_channel_enable(DMA0, DMA_CH3);

然后添加几个全局变量如下:

/* 发送缓存 */
#define UART0_TX_LEN        256             /* 单次最大发送缓存字节数 */
uint8_t UART0_TX_BUF[UART0_TX_LEN];         /* 发送缓冲区 */
uint8_t DMA_BUF_BUSY = 0 ;                 /* 缓冲区是否已被占用 */

自定义uart0打印函数:

/* 自定义UART0 printf 函数* 参数:带发送的字符串,确保一次发送数据不超过UART0_TX_LEN字节* 返回值:无  */
void u1_printf(char* fmt,...)
{uint32_t i;va_list ap; va_start(ap,fmt);while(DMA_BUF_BUSY == 1);DMA_BUF_BUSY = 1;vsprintf((char*)UART0_TX_BUF,fmt,ap);va_end(ap);UART0_TX_BUF[UART0_TX_LEN-1] = '\0';/* 计算此次发送数据的长度 */i=strlen((const char*)(UART0_TX_BUF));/* 设置DMA传输 */dma_channel_disable(DMA0, DMA_CH3);       /* 关闭DMA传输才可以进行设置 */dma_memory_address_config(DMA0,DMA_CH3,(uint32_t)(UART0_TX_BUF));dma_transfer_number_config(DMA0,DMA_CH3,i);dma_channel_enable(DMA0, DMA_CH3);      /* 开启DMA传输 */
}

因为使用到了DMA中断,使用编写DMA0通道3中断服务函数

/* DMA0 通道3 中断服务函数* 参数:无* 返回值:无    */
void DMA0_Channel3_IRQHandler(void)
{/* 清除DMA0 通道3 中断标志位 */dma_interrupt_flag_clear(DMA0, DMA_CH3, DMA_INT_FLAG_G);/* 进入中断,表示已经传输完成缓冲区,释放缓冲区 */if(DMA_BUF_BUSY == 1) DMA_BUF_BUSY = 0;
}

三、修改主函数

将主函数的while循环修改为如下所示

    while(1){/* 通过串口打印 Hello world! */u1_printf("Hello world! ");u1_printf("I am William. \r\n");/* turn on LED */LED(1);delay_1ms(500);/* turn off LED */LED(0);delay_1ms(500);}

四、功能验证

编译链接烧录到小熊派开发板,通过串口调试助手可以看到成功打印:

五、附录

完整代码我存放在码云,可以查看:https://gitee.com/william_william/BearPi-GD32F303RGT6.git
上一篇:小熊派gd32f303学习之旅(3)—串口打印第一个Hello world程序
下一篇:小熊派gd32f303学习之旅(5)—使用DMA和空闲中断实现串口接收

小熊派gd32f303学习之旅(4)—使用DMA实现串口打印相关推荐

  1. 小熊派gd32f303学习之旅(3)—串口打印第一个Hello world程序

    小熊派gd32f303学习之旅(3)-串口打印第一个Hello world程序 一.硬件连接 通过查看原理图我们可以看到,当[UART通信选择开关]拨向[AT-MCU]时,USB虚拟串口连接到MCU的 ...

  2. 小熊派gd32f303学习之旅(7)—使用PWM实现LED呼吸灯

    小熊派gd32f303学习之旅(7)-使用PWM实现LED呼吸灯 一.前言 通过查看gd32f30x的参考手册,可以知道gd32f303的通用定时器和高级定时器可以硬件生成PWM波,然后我们查看gd3 ...

  3. 小豆包的学习之旅:里程计运动模型

    星球大战里面有2个非常出色的机器人一个是3PO,一个是R2.我的机器人呢就叫小豆包啦,代号FR2,不许侵犯它的署名哦. 常见的机器人运动模型包括:速度计运动模型,里程计运动模型和惯导运动模型.概率运动 ...

  4. 如何利用小熊派获取MPU6050六轴原始数据

    摘要:使用小熊派开发板,通过硬件IIC与MPU6050六轴传感器模块通信,完成相应寄存器配置,成功获取陀螺仪.加速度计数据. 本问主要讲述使用小熊派开发板+MPU6050六轴传感器,获取加速度计以及陀 ...

  5. 小熊派IoT开发板系列教程正式发布——免费学习

    小熊派介绍 小熊派IoT开发板一款由南京厚德物联网有限公司联合华为技术有限公司基于STM32L431RCT6设计的高性能物联网开发板.开发板充分考虑物联网感知层设备的多样性,具有强大的可扩展性,用于提 ...

  6. 2021物联网开发学习——基于小熊派IoT开发板Bear-Pi-IOT、E53_IA1_智慧农业拓展板与小熊派-鸿蒙·季Bear-Pi-HM Nano并接入Hi-Link

    2021物联网开发学习--基于小熊派IoT开发板Bear-Pi-IOT.E53_IA1_智慧农业拓展板与小熊派-鸿蒙·季Bear-Pi-HM Nano并接入Hi-Link 目录 作者介绍 目的 用到的 ...

  7. 泰凌微ble mesh蓝牙模组天猫精灵学习之旅 ② 如何实现 微信小程序蓝牙控制 Ble Mesh模组 安信可TB02,全部开源!

    本<泰凌微ble mesh蓝牙模组天猫精灵学习之旅>系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1.小 ...

  8. 小猪的Python学习之旅 —— 18.Python微信转发小宇宙早报

    小猪的Python学习之旅 -- 18.Python微信转发小宇宙早报 标签:Python 一句话概括本文: 利用itchat,监控特定信息,转发到特定微信群- 引言: 上一篇 小猪的Python学习 ...

  9. python风变编程知乎_风变编程Python小课学习之旅

    先说说我是怎样与Python结缘的吧,我之前一直就职在互联网公司,是负责公司品牌设计的,已从事设计工作十余年了,也是到了一个瓶颈期,过去的知识已经快跟不上时代的发展,想给自己充充电,拓展一下知识.在今 ...

最新文章

  1. 如何定制一款12306抢票浏览器——处理预订页面和验证码自动识别功能
  2. ps光效插件_全套光效PS插件(2019),只有你想不到的,没有它做不到的PS特效...
  3. 【前端词典】和媳妇讲代理后的意外收获
  4. JVM 调优实战--常用命令参数及PS收集器的GC日志格式
  5. C++中vector容器为什么扩容时按照2倍或者1.5倍进行扩容
  6. 解决MySQL Server Logs不能正常查看的问题
  7. 第五站 使用winHex利器加深理解数据页
  8. 《大数据》专题征文:大数据可视分析技术与应用
  9. Faster RCNN杂谈
  10. setInterval 和$interval的区别
  11. 08.CXF发布WebService(Java项目)
  12. 开发power apps canvas时用到的一些公式和小技能
  13. Unity3D说明文档翻译-Physics Manager
  14. bilibili技术总监毛剑:B站高可用架构实践
  15. 阿里云云计算ACP实验考试之使用OSS对图片进行基本处理
  16. Vertica 常用命令
  17. 怎样设置一个函数C语言,C语言中怎样编写一个函数 如何在C语言中定义一个函数?...
  18. 诊断DB2 Java应用程序的性能问题
  19. web连接mysql教程视频_jsp servlet mysql实现的Java web在线商城项目源码附带视频指导运行教程...
  20. 随身WIFI折腾日记(一)---霓虹灯

热门文章

  1. dubbo服务暴露流程总结
  2. 程序员的工资有多高?
  3. 【BJOI2019】排兵布阵 DP
  4. 美国电子烟走向规范化,“下一站”是中国?
  5. 孙俪主演的热播剧《安家》房似锦,让我们看到比贫穷更可怕的是原生家庭
  6. linux系统输入数字 求最大值,写函数,输入n个数字输出最大值和最小值
  7. ActivityManager: Waited long enough for:****Service
  8. pandas实现股票日线数据转周线,月线等
  9. Python pip distribute
  10. 居然可以用jQuery实现360度汽车产品3D旋转展示酷炫特效 使用你的小鼠标来试试吧