完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
背景
在单片机的开发中,经常需要使用printf函数来监测程序运行中的一些变量,但是在程序中添加printf函数会影响程序的执行速度,尤其在一些对时间要求比较高的函数中,会造成比较大的延时,以9600bps的速度来说,发送一个字节(8位,无奇偶校验)需要 1 * 10 / 9600 = 1.04ms。那发送10个字节就有10ms左右的延时,对于一些函数来说可能无法容忍这么大的延迟。因此使用DMA的方式就显得比较重要。 实现思路 实现printf函数主要就是要改写fputc函数 int fputc(int ch, FILE *f) 但是fputc函数每次只能发送一个字节,如果我们把fputc函数直接改成: int fputc(int ch, FILE *f) { HAL_UART_Transmit_DMA(&PrintUartHandle, (uint8_t *)&ch, 1); return (ch); } 那么至少存在两个问题: 1、DMA每次都发送一个字节,效率比较低。 2、频繁调用fputc,可能DMA上一次的数据还没有发送完,导致这次发送失败。 例如: printf("HelloWorldrn"); printf先发送H,调用fputc函数,此时DMA开始工作。由之前的分析可知,对于9600bps来说,需要1ms才能把字符H发送完成。在这1ms之内elloWolrdrn都会调用fputc函数,但由于DMA还没有发送完成,会导致其他的字符发送失败。最终成功发出去的只有第一个字符H。 如果想用调用DMA,就要想其他的办法。因为printf函数最终是调用fputc函数的,所以我们要在fputc函数中想办法。我们需要做以下处理: 1、如果fputc函数中DMA是空闲状态的话,那么向DMA中放入数据,并启动DMA发送。 2、如果fputc函数中的DMA现在忙,那么需要把数据暂时存储起来。 3、如果数据发送完成,那么需要判断暂存区有没有数据,如果有数据则需要把暂存区的所有数据都通过DMA发送出去。 那么现在这个问题的关键是在这个暂存区怎么实现,可以想象的出来的,这个暂存区应该是一个环形队列。 |
|
|
|
只有小组成员才能发言,加入小组>>
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
412 浏览 1 评论
273 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
243 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
607 浏览 2 评论
631 浏览 2 评论
1355浏览 9评论
35浏览 3评论
STM32CUBEMX4.22.1在main函数里面添加一行语句就死机的原因?
36浏览 3评论
37浏览 3评论
KEIL MDK为什么无法debug library中的代码?
75浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-4-24 22:26 , Processed in 0.536901 second(s), Total 45, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号