【目的】
在单片机的调试中,我们日常的日志输出,通常是通过串口来实现,而通过串口重定向来实现又是常规的操作之一。这次我在前面的基础之上增加了printf的面向对象的增加这项功能。
【实现步骤】
1、在工程中添加printf.c函数,并把他加入到libs的分组之中。

2、在工程的设置中,打开Use MincroLIB库。

3、在printf.c中,添加对输入输出的系统头文件<stdio.h>的引用,当然由于我需要调用驱动库要添加<devices.h>以及<hal_data.h>的引用。
4、重写fputc输出,在此函数中,我先查找Log这个串口的驱动,如果查找到,则使用他的write进行串口输出,代码如下:
int fputc(int ch, FILE *f)
{
(void)f;
struct UartDev *pLogDevice = UartDeviceFind("Log");
pLogDevice->Write(pLogDevice, (unsigned char*)&ch, 1);
return ch;
}5、重写scanf函数,在这个函数中,我也一样先查找以"Log"命名的串口,如果查找到,则使用这个驱动的write进行输出。其代码如下:
int fgetc(FILE *f)
{
uint8_t ch;
(void)f;
struct UartDev *pLogDevice = UartDeviceFind("Log");
/* 启动接收字符 */
while(pLogDevice->Read(pLogDevice, (unsigned char*)&ch, 1) != 1)
{}
/* 回显 */
{
fputc(ch, &__stdout);
/* 回车之后加换行 */
if (ch == '\r')
{
fputc('\n', &__stdout);
}
}
return (int)ch;
}6、驱动设置好后,就可以在工程中使用printf进行串口输出了。
添加测试代码如下:
void led_blink(void)
{
uint32_t cnt;
UartDevicesRegister();
LedDevice *pLED = LedGetDevice();
if(NULL == pLED)
{
printf("Error. There is no LED device!\r\n");
return;
}
pLED->Init(pLED);
while(1)
{
cnt++;
pLED->On(1);
R_BSP_SoftwareDelay(1,BSP_DELAY_UNITS_SECONDS);
pLED->Off(1);
R_BSP_SoftwareDelay(1,BSP_DELAY_UNITS_SECONDS);
pLED->On(2);
R_BSP_SoftwareDelay(1,BSP_DELAY_UNITS_SECONDS);
pLED->Off(2);
R_BSP_SoftwareDelay(1,BSP_DELAY_UNITS_SECONDS);
printf("run cnt %d\r\n",cnt);
}
}测试结果如下:

【总结】
使用面向对象之编程,可以实现代码的快递移植,当然重写printf也是非常之简单。
我要赚赏金
