STM32以DMA方式实现printf函数

背景

在单片机的开发中,经常需要使用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("HelloWorld\r\n");

printf先发送H,调用fputc函数,此时DMA开始工作。由之前的分析可知,对于9600bps来说,需要1ms才能把字符H发送完成。在这1ms之内elloWolrd\r\n都会调用fputc函数,但由于DMA还没有发送完成,会导致其他的字符发送失败。最终成功发出去的只有第一个字符H。

未完待续

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页