小熊派gd32f303学习之旅(4)—使用DMA实现串口打印
小熊派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实现串口打印相关推荐
- 小熊派gd32f303学习之旅(3)—串口打印第一个Hello world程序
小熊派gd32f303学习之旅(3)-串口打印第一个Hello world程序 一.硬件连接 通过查看原理图我们可以看到,当[UART通信选择开关]拨向[AT-MCU]时,USB虚拟串口连接到MCU的 ...
- 小熊派gd32f303学习之旅(7)—使用PWM实现LED呼吸灯
小熊派gd32f303学习之旅(7)-使用PWM实现LED呼吸灯 一.前言 通过查看gd32f30x的参考手册,可以知道gd32f303的通用定时器和高级定时器可以硬件生成PWM波,然后我们查看gd3 ...
- 小豆包的学习之旅:里程计运动模型
星球大战里面有2个非常出色的机器人一个是3PO,一个是R2.我的机器人呢就叫小豆包啦,代号FR2,不许侵犯它的署名哦. 常见的机器人运动模型包括:速度计运动模型,里程计运动模型和惯导运动模型.概率运动 ...
- 如何利用小熊派获取MPU6050六轴原始数据
摘要:使用小熊派开发板,通过硬件IIC与MPU6050六轴传感器模块通信,完成相应寄存器配置,成功获取陀螺仪.加速度计数据. 本问主要讲述使用小熊派开发板+MPU6050六轴传感器,获取加速度计以及陀 ...
- 小熊派IoT开发板系列教程正式发布——免费学习
小熊派介绍 小熊派IoT开发板一款由南京厚德物联网有限公司联合华为技术有限公司基于STM32L431RCT6设计的高性能物联网开发板.开发板充分考虑物联网感知层设备的多样性,具有强大的可扩展性,用于提 ...
- 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 目录 作者介绍 目的 用到的 ...
- 泰凌微ble mesh蓝牙模组天猫精灵学习之旅 ② 如何实现 微信小程序蓝牙控制 Ble Mesh模组 安信可TB02,全部开源!
本<泰凌微ble mesh蓝牙模组天猫精灵学习之旅>系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1.小 ...
- 小猪的Python学习之旅 —— 18.Python微信转发小宇宙早报
小猪的Python学习之旅 -- 18.Python微信转发小宇宙早报 标签:Python 一句话概括本文: 利用itchat,监控特定信息,转发到特定微信群- 引言: 上一篇 小猪的Python学习 ...
- python风变编程知乎_风变编程Python小课学习之旅
先说说我是怎样与Python结缘的吧,我之前一直就职在互联网公司,是负责公司品牌设计的,已从事设计工作十余年了,也是到了一个瓶颈期,过去的知识已经快跟不上时代的发展,想给自己充充电,拓展一下知识.在今 ...
最新文章
- 如何定制一款12306抢票浏览器——处理预订页面和验证码自动识别功能
- ps光效插件_全套光效PS插件(2019),只有你想不到的,没有它做不到的PS特效...
- 【前端词典】和媳妇讲代理后的意外收获
- JVM 调优实战--常用命令参数及PS收集器的GC日志格式
- C++中vector容器为什么扩容时按照2倍或者1.5倍进行扩容
- 解决MySQL Server Logs不能正常查看的问题
- 第五站 使用winHex利器加深理解数据页
- 《大数据》专题征文:大数据可视分析技术与应用
- Faster RCNN杂谈
- setInterval 和$interval的区别
- 08.CXF发布WebService(Java项目)
- 开发power apps canvas时用到的一些公式和小技能
- Unity3D说明文档翻译-Physics Manager
- bilibili技术总监毛剑:B站高可用架构实践
- 阿里云云计算ACP实验考试之使用OSS对图片进行基本处理
- Vertica 常用命令
- 怎样设置一个函数C语言,C语言中怎样编写一个函数 如何在C语言中定义一个函数?...
- 诊断DB2 Java应用程序的性能问题
- web连接mysql教程视频_jsp servlet mysql实现的Java web在线商城项目源码附带视频指导运行教程...
- 随身WIFI折腾日记(一)---霓虹灯
热门文章
- dubbo服务暴露流程总结
- 程序员的工资有多高?
- 【BJOI2019】排兵布阵 DP
- 美国电子烟走向规范化,“下一站”是中国?
- 孙俪主演的热播剧《安家》房似锦,让我们看到比贫穷更可怕的是原生家庭
- linux系统输入数字 求最大值,写函数,输入n个数字输出最大值和最小值
- ActivityManager: Waited long enough for:****Service
- pandas实现股票日线数据转周线,月线等
- Python pip distribute
- 居然可以用jQuery实现360度汽车产品3D旋转展示酷炫特效 使用你的小鼠标来试试吧