完善资料让更多小伙伴认识你,还能领取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发送出去。 那么现在这个问题的关键是在这个暂存区怎么实现,可以想象的出来的,这个暂存区应该是一个环形队列。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1877 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1661 浏览 1 评论
1145 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
760 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1720 浏览 2 评论
1963浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
789浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
612浏览 3评论
629浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
591浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-12 03:26 , Processed in 0.581709 second(s), Total 43, Slave 38 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号