Keil重定向printf到串口UART输出

2018-06-10 11:22:18来源: eefocus 关键字:Keil  重定向printf  串口  UART输出

下面是我搜索到的可以借鉴的讨论+我的评述

评述:在一个芯片系统里,uart的驱动是厂商自己写好的,那他们是怎么关联printf到uart的呢?有人说,printf最终是调用了putchar,我搜索了源码,没有这个函数,估计是开发工具,像KeilC u3,里面已经集成了putchar。于是我奇怪,这个工具怎么知道厂商哪个函数时uart的,有没有命名规则要求?好像没有,看了下面的讨论,估计是通过UART的收发寄存器来关联的。我猜想应该是在某个地方,keilc关联了系统的寄存器列表,找到了串口的寄存器的地址,然后putchar操作该寄存器,就相当于操作了厂商或者开发者自定义的uart_write_byte.uart_read_byte.

所以在keilc里,别人写好的系统,可以直接调用printf输出。我觉得要弄明白,得研究下keil是怎么处理库函数和寄存器的关系的。


关于putchar函数,估计printf是通过

http://www.amobbs.com/thread-5479867-1-1.html


就是在你配置完串口的时候首先写一个数到SBUF寄存器中然后在用printf函数打印就可以,当让这个顺序是不可以变的,如果你想在追问细节为什么,我只能告诉你这应该是开发环境决定的,这一点我就理解这么多,如果有大侠给出更好的解释我也一起共勉。


其实也不用首先写一个数据到SBUF寄存器,只需在串口初始化后,加上一句TI=1;即可。原因是printf函数事实上是调用putchar输出字符的。之所以能输出到串口上,就是因为putchar函数把字符通过串口输出。
这是keil中putchar最简单的版本,其他版本也一样,看函数就明白为什么要先让TI=1;了,楼主写的那个SBUF=0,原理是相同的,写入了数据,那么TI就等于1了,然后就可以使用putchar函数和printf函数了。
putchar函数的源码在{keil安装目录下}\C51\LIB文件夹里的PUTCHAR.C文件里,另外在keil的帮助文档里有说明

char putchar (char c)  {

  while (!TI);

  TI = 0;

  return (SBUF = c);

}

从下面这篇文章中,我好像找到答案了

评述:我在某个CortextM3的源码里的debug.c找到了fputc。应该说,某些系统是通过fputc建立联系,而不是putchar的。如下:


void fputc_hook(char ch)  

{  

    if (DebugType == 0)  

    {  

        UARTWriteByte(ch, 1000);  

    }  

    else  

    {  

        VirtualUartWrite(ch);  

    }  

}  

  

int fputc(int ch, FILE *f)  

{  

    uint8 dgbBuffer[DEBUG_TIME_LEN];  

    uint32 tmpcnt, i;  

  

    if (ch == '\n')  

    {          

        tmpcnt = SysTickCounter;  

        for (i = 0; i < DEBUG_TIME_LEN; i++)  

        {  

            dgbBuffer[i] = tmpcnt % 10;  

            tmpcnt = tmpcnt / 10;  

        }  

          

        fputc_hook('\r');  

        fputc_hook('\n');  

        fputc_hook('[');  

        for (i = 0; i < DEBUG_TIME_LEN; i++)  

        {  

            fputc_hook(dgbBuffer[DEBUG_TIME_LEN - 1 -i]+0x30);  

            if (DEBUG_TIME_LEN - 1 -i == 2)  

            {  

                fputc_hook('.');  

            }  

        }  

        fputc_hook(']');  

          

        return OK;  

    }  

      

    fputc_hook(ch);  

  

    return OK;  

}  

下面是参考文章的转载:
http://blog.chinaunix.net/uid-27631233-id-3345008.html


    在实际工作中,遇到了这么一个问题,需要向不同的串口传输ASCII码,无疑使用printf函数是最方便的。然而printf打印出的信息无法选择出口。在网上搜到的程序,printf要调用fputc函数发送字符。该函数如下:


int fputc(int ch, FILE *f)
{
  /* e.g. write a character to the USART */
  USART_SendData(USART1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

    入口参数有字符和字符要输出到的文件指针。根据搜索,printf函数输出到stdout,而fprintf可以指定字符到达的文件。可FILE结构体中,没有一个是与串口相关的。

typedef struct {
  char *fpos; /* Current position of file pointer (absolute address) */
  void *base; /* Pointer to the base of the file */
  unsigned short handle; /* File handle */
  short flags; /* Flags (see FileFlags) */
  short unget; /* 1-byte buffer for ungetc (b15=1 if non-empty) */
  unsigned long alloc; /* Number of currently allocated bytes for the file */
  unsigned short buffincrement; /* Number of bytes allocated at once */
} FILE;

    该如何重定向呢?不知道。但有一个弥补的方法。
    自己定义n个FILE*指针,并任意赋值。在fputc中利用if..else来做判断,代码如下:

FILE* FileUart1 = (FILE*)0x19;
FILE* FileUart2 = (FILE*)0x28;
int fputc(int ch, FILE *f) {
  if ( f == FileUart1 ) {
    USART_SendData(COM_USART[0], (uint8_t) ch);
    while (USART_GetFlagStatus(COM_USART[0], USART_FLAG_TC) == RESET){}
  }
  else if ( f == FileUart2 ) {
    USART_SendData(COM_USART[1], (uint8_t) ch);
    while (USART_GetFlagStatus(COM_USART[1], USART_FLAG_TC) == RESET){}
  }
}

    这样,fprintf(FileUart1,...)和fprintf(FileUart2,...)便能向不同的串口发送数据。哈哈,虽然没有真正做到重定向,只是用了个歪招,但最初的目的还是达到了。


关键字:Keil  重定向printf  串口  UART输出

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/article_2018061039720.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32F103程序串口调用printf打印数据
下一篇:最后一页

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

网友正在学习IC视频

推荐阅读
全部
Keil
重定向printf
串口
UART输出

小广播

独家专题更多

东芝在线展会——芯科技智社会创未来
东芝在线展会——芯科技智社会创未来
2017东芝PCIM在线展会
2017东芝PCIM在线展会
TI车载信息娱乐系统的音视频解决方案
TI车载信息娱乐系统的音视频解决方案
汇总了TI汽车信息娱乐系统方案、优质音频解决方案、汽车娱乐系统和仪表盘参考设计相关的文档、视频等资源

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2018 EEWORLD.com.cn, Inc. All rights reserved