中断方式下使用Printf

Keil下使用printf函数,很方便,大家可以参考网上的其他文章。

 

Printf函数是系统自定义函数,其中内部重复调用了fputc函数,每次发送1个字节ch。

参考下述代码中#if 0的部分。

 

当发送字节数较多时,printf消耗的时间非常长,因为每次都要等待发送完成。

时间计算:串口设置115200,n,8,1,对于大包发送,一般用较快的bps。

如果发送100字节,大概1100位(算上起始位和停止位)。

消耗的时间为:1100/115200 = 9ms,实际运行时间估计要2~3倍,也就是30ms左右。

如果字节数更多或波特率更低,消耗的时间会更长。

 

考虑将printf做成中断方式,基本的流程就是:

  1. 在发送第一个字符时,立即打开串口发送;
  2. 当发送后续字符时,直接压入队列,不再等待串口发送完成;
  3. 中断函数中,如果发送队列中还有数据没有发送完成,则继续发送。

 

//重定义fputc函数

int fputc(int ch, FILE *f)

{      

#if 0

//使用poll方式发送数据

while((RS232_UART->SR&0X40)==0);//循环发送,直到发送完毕   

    RS232_UART->DR = (u8) ch;      

return ch;

#else

//使用queue方式发送数据

if(g_usmartUartState == UART_SEND)

{

QueueInput(&g_usmartTxQueue,(u8)ch);

}

else

{

g_usmartUartState = UART_SEND;

 

// QueueClear(&g_usmartTxQueue); //清除发送队列

 

RS232_UART->DR = (u8)ch;

 

USART_ITConfig(RS232_UART,USART_IT_RXNE, DISABLE);

USART_ITConfig(RS232_UART,USART_IT_TC,ENABLE);           //使能发送中断

};

#endif

 

  1. 发送队列对应的buf一定要大,因为printf没有延时了,应用执行时,短时间内可能好几个printf都往queue中塞数据(在这个时间段内,前面的数据还没有消耗完),容易塞满buf;
  2. 在矿浆项目下测试通过;

你可能感兴趣的:(软件设计)