完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
阅读全篇约花两三分钟, 可以先上杯茶, 慢慢细看~~~
玩STM32好几年了,常用DMA传输数据,好给MCU省下资源去干干其它的事。 理念中,DMA = 又省又快!这是被书本灌输的知识。到底有多快有多少省呢?今天手痒,写了个测试代码,结果还真有些惊喜! 将分别测试USART通过printf、DMA两种方式,测试输出数据(TX)时,在耗时、速度上的差别。 一、测试环境 硬件: F103C8 (还是这个大爱的魔女开发板,贼好用) 软件: Keil_5.27(5.27!!!) 上位机: 秉火串口调试助手(V1.0最好用) 逻辑分析软件: pulseview(开源,界面和设置都很简洁) 二、测试用代码 1、代码三处要点 红点处:自定义的运行时长观察函数,放置在3个地方,获取期间两段运行时长,单位是us ; 黄色1: printf(), 就是平时l输出至上位机的 printf(), 其底层fputc已重定向输出至USART1, 黄色2:print(), 注意名称少了个f,自定义的函数, USART1通过DMA输出参数传递的字符串; 2、普通发送printf()函数, fputc的重定向代码 // 重定向fputc函数 // printf的输出,指向fputc,由fputc输出到串口 // 这里使用串口1(USART1)输出printf信息 int fputc(int ch, FILE *f) { // 重要判断 if(xFlag.PrintfOK == 0) return 0; // 判断USART是否已配置,防止在配置前调用printf被卡死 while((USARTx ->SR&0X40)==0); // 等待上一次串口数据发送完成 USARTx ->DR = (u8) ch; // 写DR,串口1将发送数据 return ch; } 3、DMA配置代码,print()函数 /****************************************************************************** * 函 数: print * 功 能: UART使用DMA发送数据 * 参 数: u8* charTemp 要发送的字符串首地址 * 返回值: * 备 注: 魔女开发板团队 资料存放Q群:262901124 最后修改_2020年05月10日 ******************************************************************************/ void print(char* charTemp) { u32 num = 0; char* t=charTemp ; while(*t++ !=0) num++; RCC->AHBENR|=1<<0; // 开启DMA1时钟 DMA1_Channel4->CPAR = (u32)&USARTx->DR; // 外设地址 DMA1_Channel4->CMAR = (u32)charTemp; // 存储器地址 DMA1_Channel4->CNDTR = num; // 传输数据量 DMA1_Channel4->CCR = 1<<4; // 数据传输方向 0:从外设读 1:从存储器读 DMA1_Channel4->CCR |= 0<<5; // 循环模式 0:不循环 1:循环 DMA1_Channel4->CCR |= 0<<6; // 外设地址非增量模式 DMA1_Channel4->CCR |= 1<<7; // 存储器增量模式 DMA1_Channel4->CCR |= 0<<8; // 外设数据宽度为8位 DMA1_Channel4->CCR |= 0<<10; // 存储器数据宽度8位 DMA1_Channel4->CCR |= 0<<12; // 中等优先级 DMA1_Channel4->CCR |= 0<<14; // 非存储器到存储器模式 DMA1_Channel4->CCR |= 1<<0; // 开启DMA传输 } 三、运行耗时 - 测试结果 使用printf()和print()通过USART1输出27个字节, 然后把监察到的运行时长打印到上位机,结果如下: 1、直接数据 数据处理的耗时相差230倍!!! 使用DMA省99.5%的耗时!!! 2、理解思考 printf的耗时,应该耗在每发一个字节,芯片都要while(), 一个字节挨一个字节地while()死等着发送, 计算可知115200波特率下,每一个字节要87us, 那27个字节, 它就要等待27次87us , 就是 2343us了, 加上命令处理时间, 打印中的结果2769us, 差不多是这个时间了. 注意, 这个在等人的主角是芯片, 这个时候它是不能干其它的事情的, 除非有中断突然出现. 特别特别地注意: 如果死等的这个时候有中断出现, 而中断处理时长超过87us, 那就会有另一个头疼的问题: USART的数据被打断打乱! 而print通过DMA发送,12us的耗时应该就是代码指令操作的时间:主芯片给运输队伍下命令:你们去A地方,把num个纸箱,搬到B地方。几句话, 用时12us. 我们再进一步: 12us是主芯片动动嘴皮下命令的时长,不是运输队伍工作的时长,那它需要工作多长时间呢? 四、逻辑分析仪 - 测试结果 直接上波形的运行截图, 两个截图都是发送27个字节的波形时长: 可以看到,printf产生波型比DMA耗时, 大概多10%左右的时间, 但两者的波型时长相差很小, 说明尽管在输出数据时处理方式不同, 芯片运行耗时两者相差巨大, 但最终在硬件产生数据波型的工作中, 都得按协议走. 1、计算分析 说说printf产生波型要比DMA耗时多的理解: 上面计算过, 波特率115200时, 每个字节占用10个时钟, 计算数值是每个字节波形长86.8us, 27个字节的波型总长是2343us, 这个计算数值和在DMA传输时的实测数值2344us是一致的;但是使用printf的while死等输出, 27字节的数据波形时长要2579us, 足足多了236us, 应该是每两个字节间得处理死等的判断代码和命令, 造成了字节与字节间的空白浪费; 2、疑问 还有1个小问题, 暂时没找到答案: 在使用自定义的print函数通过DMA发送数据, 200字节左右, 数据都是准确的, 但大约500字节以上时,出现头尾的数据有失真的情况,不是偶然发生, 是每次都在同样的位置出现小量数据错误, 多次排查均没有发现问题所在, 先做个记录, 后续有时间再放灯下挑挑. 如果有朋友需要测试中的完整代码, 可在留言区留下邮箱. 欢迎拍砖头!! |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1618 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1545 浏览 1 评论
979 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1597 浏览 2 评论
1864浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
645浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
516浏览 3评论
532浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
505浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 17:51 , Processed in 0.826723 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号