精华内容
下载资源
问答
  • 2021-01-08 16:16:46

    方法一:

    在STM32Cube软件生成的usart.c中加入下面的代码就可以了

    
    /* USER CODE BEGIN 1 */
    /*printf() 重定向输出到串口*/
    #ifdef __GNUC__
    	#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    #else
    	#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    
    #endif /*__GNUC__*/
    
    PUTCHAR_PROTOTYPE
    {
    	/*通过串口1发送一个字符,ch为字符的存储地址,0xffff为超时时间*/
    	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
    	return ch;
    }
    /* USER CODE END 1 */
    

    方法二:

    在STM32Cube软件生成的mian.c中加入下面的代码就可以了

    /* USER CODE BEGIN 0 */
    #ifdef __GNUC__
      /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
         set to 'Yes') calls __io_putchar() */
      #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    #else
      #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    #endif /* __GNUC__ */
    /**
      * @brief  Retargets the C library printf function to the USART.
      * @param  None
      * @retval None
      */
    PUTCHAR_PROTOTYPE
    {
        HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
        return ch;
    }
    /* USER CODE END 0 */
    

    三、

    如果显示error: #20: identifier “FILE” is undefined报错在usart.c中加入:

    /* USER CODE BEGIN 0 */
    #include "stdio.h"
    /* USER CODE END 0 */
    

    或者加入FILE结构体定义:

    typedef struct __FILE FILE;
    
    更多相关内容
  • 单片机printf详解

    千次阅读 2021-03-08 16:33:28
    文章目录总结描述格式标志字段(flags)宽度字段(width)精度(.precision)类型字段(type)错误示例检测示例 总结 #include <stdio.h> int printf ( ...printf函数格式化一系列字符串和数值,并使用putc

    总结

    #include <stdio.h>
    
    int printf (
      const char *fmtstr         /* format string */
      <[>, arguments ... <]>);   /* additional arguments */
    

    描述

    printf函数格式化一系列字符串和数值,并使用putchar函数构建一个字符串以写入输出流。

    fmtstr参数是一个格式字符串,可以由字符,转义序列和格式规范组成。

    普通字符和转义序列按它们解释的顺序复制到流中。格式规范始终以百分号(’%’)开头,并且要求在printf函数调用中包括其他参数。

    从左到右读取格式字符串。遇到的第一个格式规范引用了fmtstr之后的第一个参数,并使用格式规范对其进行转换和输出。

    第二个格式规范访问fmtstr之后的第二个参数,依此类推。如果参数多于格式规范,则多余的参数将被忽略

    如果没有足够的参数用于格式规范,或者参数类型与fmtstr指定的参数类型不匹配,则结果是不可预测的。

    格式

    格式规范具有以下常规格式:

    % <[>flags<]> <[>width<]> <[>.precision<]> <[>{b|B|l|L}<]> type
    

    格式规范中的每个字段可以是单个字符或指定特定格式选项的数字。

    标志字段(flags)

    标志字段是一个字符,用于证明输出的正当性并打印+/-符号和空白,小数点以及八进制和十六进制前缀,如下表所示。

    FlagDescription翻译
    -Left justify the output in the specified field width.左对齐指定字段宽度的输出。
    +Prefix the output value with a + or - sign if the output is a signed type.如果输出是带符号类型,则在输出值前加上+或-前缀
    blank(’’)Prefix the output value with a blank if it is a signed positive value. Otherwise, no blank is prefixed.如果输出值是有符号正值,则将其前缀为空白。 否则,不带空格前缀
    #Prefixes a non-zero output value with 0, 0x, or 0X when used with o, x, and X field types,
    respectivelyWhen used with the e, E, f, g, and G field types,the # flag forces the output value to include a decimal point.The # flag is ignored in all other cases.
    当分别与o,x和X字段类型一起使用时,将非零输出值前缀为0、0x或0X。
    与e,E,f,g和G字段类型一起使用时,#标志强制输出值包含小数点。
    在所有其他情况下,#标志将被忽略。

    宽度字段(width)

    宽度字段是一个非负数,它指定最少要打印的字符数。 如果输出值中的字符数小于宽度,则在左侧(默认情况下)或右侧(指定-标志时)添加空格以填充到最小宽度。 如果width前缀为’0’,则填充零而不是空格。 width字段不会截断输出。 如果输出值的长度超过指定的宽度,则输出所有字符。

    精度(.precision)

    精度字段是一个非负数,它指定要打印的字符数,有效数字数或小数位数。 下表中指定了浮点数时,精度字段可能会导致输出值的截断或舍入。

    TypePrecision Field Meaning翻译
    d,u,o,x,XThe precision field specifies the minimum number of digits that are included in the output value. Digits are not truncated if the number of digits in the argument exceeds that defined in the precision field. If the number of digits in the argument is less than the precision field, the output value is padded on the left with zeros.精度字段指定输出值中包含的最小位数。 如果参数中的位数超过精度字段中定义的位数,则位数不会被截断。 如果参数中的位数小于precision字段,则在输出值的左侧填充零。
    fThe precision field specifies the number of digits to the right of the decimal point. The last digit is rounded.精度字段指定小数点右边的位数。
    最后一位四舍五入。
    e.EThe precision field specifies the number of digits to the right of the decimal point. The last digit is rounded.精度字段指定小数点右边的位数。
    最后一位四舍五入。
    g,GThe precision field specifies the maximum number of significant digits in the output value.精度字段指定输出值中的最大有效位数。
    sThe precision field specifies the maximum number of characters in the output value. Excess characters are not output.精度字段指定输出值中的最大字符数。
    不输出多余的字符。
    c,pThe precision field has no effect on these field types.精度字段对这些字段类型没有影响.

    类型字段(type)

    类型字段type是一个单个字符,用于指定将参数解释为字符,字符串,数字还是指针,如下表所示。

    TypeArgument TypeInput Format翻译
    dintSigned decimal number.有符号十进制
    uunsigned intUnsigned decimal number.无符号十进制
    ounsigned intUnsigned octal number.无符号八进制
    xunsigned intUnsigned hexadecimal number using “0123456789abcedf”.无符号十六进制(小写)
    Xunsigned intUnsigned hexadecimal number using “0123456789ABCDEF”.无符号十六进制(大写)
    ffloatFloating-point number formatted as
    <[>-<]>dddd.dddd.
    浮点数
    efloatFloating-point number formatted as
    <[>-<]>d.dddde<[>-<]>dd.
    科学计数法(e)
    EfloatFloating-point number formatted as
    <[>-<]>d.ddddE<[>-<]>dd.
    科学计数法(E)
    gfloatFloating-point number using either the e or f format, whichever is more compact for the specified value and precision.灵活选择e或者f的格式,
    让数据的输出更加好看有效
    GfloatFloating-point number using either the E or f format, whichever is more compact for the specified value and precision.灵活选择E或者f的格式,
    让数据的输出更加好看有效
    ccharA single character.一个字符(原始数据是什么就是什么)
    s*A string of characters terminated by a null character (’\0’).一串以空字符(’\ 0’)结尾的字符。
    p*A generic pointer formatted as t:aaaa where t is the memory type and aaaa is the hexadecimal address.通用指针,格式为t:aaaa,
    其中t是内存类型,
    而aaaa是十六进制地址。

    错误示例

    	 unsigned char a = 5;
    	 Delay1000ms();
    	 TI = 1;
    	 printf("%d", a);	
    

    在这里插入图片描述
    这里不对的原因是因为格式化为为%d是有符号整形,而放上的数据为无符号字符型。一个是16位,而放上的是8位,在printf中会将8位左移形成16位发出。 因此使用printf必须注意类型!
    在这里插入图片描述

    检测示例

    #include <stdio.h>
    
    void tst_printf (void) {
      char a = 1;
      int b  = 12365;
      long c = 0x7FFFFFFF;
    
      unsigned char x = 'A';
      unsigned int y  = 54321;
      unsigned long z = 0x4A6F6E00;
    
      float f = 10.0;
      float g = 22.95;
    
      char buf [] = "Test String";
      char *p = buf;
    
      printf ("char %bd int %d long %ld\n",a,b,c);
      printf ("Uchar %bu Uint %u Ulong %lu\n",x,y,z);
      printf ("xchar %bx xint %x xlong %lx\n",x,y,z);
      printf ("String %s is at address %p\n",buf,p);
      printf ("%f != %g\n", f, g);
      printf ("%*f != %*g\n", (int)8, f, (int)8, g);
    }
    
    

    • <[>-<]>表示符号
    • 可选字符l或L可以紧接在类型字符之前,以分别为d,i,u,o,x和X指定长类型。
    • 可选字符b或B可以紧接在类型字符之前,以分别为d,i,u,o,x和X指定char类型。
    • 百分号后的字符未被识别为格式规范,将被视为普通字符。 例如,“ %%”将单个百分号写入输出流。
    • 必须确保参数类型与格式规范的类型匹配。您可以使用类型转换来确保将正确的类型传递给printf。
    • 此函数是特定于实现的,基于_getkey和putchar函数的操作。标准库中提供的这些函数使用微控制器的串行端口读写字符。自定义函数可以使用其他I/O设备。
    • 由于8051施加的内存限制,可传递给该函数的字节总数受到限制。在小型或紧凑型中最多可以传递15个字节。在大型模型中最多可以传递40个字节。
    展开全文
  • 用于将STC12C5608AD(28Pin)单片机中的数据上传至STC-ISP软
  • stc15单片机printf重定向

    需要修改两处

    第一处包含函库

    #include <stdio.h> //printf用
    
    

    第二处重定向

    
    ///
    //printf重定向
    char putchar(char c )
    {
        SBUF = c;
        while(!TI);
        TI = 0;
        return c;
    }
    ///

    下面就可以使用了

    int ad = 350;
    printf("AD0\t=\t%d\r\n",AD);
        

    输出结果可以使用串口调试助手的字符模式查看

    注意上面的函数调用时我已经使用别的函数进行了串口的操作。

    下面是一些不重要信息作为知识参考

    库函数关于putchar函数的描述

    这个时keil2的库文件路径

    /***********************************************************************/
    /*  This file is part of the C51 Compiler package                      */
    /*  Copyright KEIL ELEKTRONIK GmbH 1990 - 2002                         */
    /***********************************************************************/
    /*                                                                     */
    /*  PUTCHAR.C:  This routine is the general character output of C51.   */
    /*  You may add this file to a uVision2 project.                       */
    /*                                                                     */
    /*  To translate this file use C51 with the following invocation:      */
    /*     C51 PUTCHAR.C <memory model>                                    */
    /*                                                                     */
    /*  To link the modified PUTCHAR.OBJ file to your application use the  */
    /*  following Lx51 invocation:                                         */
    /*     Lx51 <your object file list>, PUTCHAR.OBJ <controls>            */
    /*                                                                     */
    /***********************************************************************/
    
    #include <reg51.h>
    
    #define XON  0x11
    #define XOFF 0x13
    
    
    /*
     * putchar (full version):  expands '\n' into CR LF and handles
     *                          XON/XOFF (Ctrl+S/Ctrl+Q) protocol
     */
    char putchar (char c)  {
    
      if (c == '\n')  {
        if (RI)  {
          if (SBUF == XOFF)  {
            do  {
              RI = 0;
              while (!RI);
            }
            while (SBUF != XON);
            RI = 0; 
          }
        }
        while (!TI);
        TI = 0;
        SBUF = 0x0d;                         /* output CR  */
      }
      if (RI)  {
        if (SBUF == XOFF)  {
          do  {
            RI = 0;
            while (!RI);
          }
          while (SBUF != XON);
          RI = 0; 
        }
      }
      while (!TI);
      TI = 0;
      return (SBUF = c);
    }
    
    
    
    #if 0         // comment out versions below
    
    /*
     * putchar (basic version): expands '\n' into CR LF
     */
    char putchar (char c)  {
      if (c == '\n')  {
        while (!TI);
        TI = 0;
        SBUF = 0x0d;                         /* output CR  */
      }
      while (!TI);
      TI = 0;
      return (SBUF = c);
    }
    
    
    /*
     * putchar (mini version): outputs charcter only
     */
    char putchar (char c)  {
      while (!TI);
      TI = 0;
      return (SBUF = c);
    }
    
    #endif
    

    也就是可以包含此文件一样能解决问题。

    参考网页

    Keil重定向printf到串口UART输出 - 电子工程世界(EEWORLD)

    关于printf函数转重定向到串口我在此讲一下!!! (amobbs.com 阿莫电子论坛)

    特此记录

    anlog

    2022年4月21日

    展开全文
  • stm32的串口重定向方法在英飞凌单片机里是不适用的,这个工程重写了一个pirntf函数来实现串口打印功能,方便调试,具体细节可以看我的博客。注意这个解决方案不是真正的重定向,只能实现字符串打印功能
  • 51单片机printf重定向

    千次阅读 2020-04-26 22:11:05
    从keil的帮助文档里我们可以看到,printf是基于putchar实现的,所以我们只要重新实现putchar,就可以实现printf的重定向,即可以将printf用在其他串口上。 putchar的函数实现在…/C51/LIB下可以找到。 #include <...

    在这里插入图片描述
    从keil的帮助文档里我们可以看到,printf是基于putchar实现的,所以我们只要重新实现putchar,就可以实现printf的重定向,即可以将printf用在其他串口上。

    putchar的函数实现在…/C51/LIB下可以找到。

    #include <reg51.h>
    
    #define XON  0x11
    #define XOFF 0x13
    
    
    /*
     * putchar (full version):  expands '\n' into CR LF and handles
     *                          XON/XOFF (Ctrl+S/Ctrl+Q) protocol
     */
    
    char putchar (char c)  {
    
      if (c == '\n')  {
        if (RI)  {
          if (SBUF == XOFF)  {
            do  {
              RI = 0;
              while (!RI);
            }
            while (SBUF != XON);
            RI = 0; 
          }
        }
        while (!TI);
        TI = 0;
        SBUF = 0x0d;                         /* output CR  */
      }
      if (RI)  {
        if (SBUF == XOFF)  {
          do  {
            RI = 0;
            while (!RI);
          }
          while (SBUF != XON);
          RI = 0; 
        }
      }
      while (!TI);
      TI = 0;
      return (SBUF = c);
    }
    

    我们来分析一下代码,首先我们先不管那两个if判断,putchar函数总是要执行的语句其实只有三句,首先先等待上一个数据发送完毕,将标志位置零以后,再发送下一个数据。这也解释了为什么我们在第一次调用printf函数时要先把TI置1,因为STC单片机复位以后TI的值为0,直接调用printf函数就会一直卡死在while(!TI)里面了。

    while(!TI);
    TI = 0;
    return (SBUF = c);
    

    if(c == '\n')部分是判断是否接收到换行符,如果接收到换行符以后,就会输出CR+LF。SBUF = 0X0d是在输出CR,推测LF是在putchar函数之外输出的。

    最后if(RI)部分是软件流控制。当接收端数据缓存区满了以后,就会向发送端发送XOFF标志,发送端接收到XOFF以后停止发送数据。接收端处理完数据以后,会向发送端发送XON标志,表示可以继续发送数据。

    使用流控制可以有效的防止数据传输过程中的丢失情况。

    分析完官方的putchar函数以后,我们需要自己写一个putchar函数来调用串口3,这里要说明一下,如果我们的工程中包含了putchar函数,编译器会优先使用我们所定义的函数,而不会去使用…/C51/LIB下的putchar函数。

    下面是我写的putchar函数,因为没有那么高的要求,所以我并没有使用流控制,其次我的代码是先发送数据,再检测标志位,我认为这样做更符合我们平时的使用习惯。

    char putchar(char c)
    {
        if (c == '\n')
        {
            S3BUF = 0x0d;
            while (!(S3CON & S3TI));  //等待发送成功
            S3CON &= ~S3TI;
            /* output CR  */
        }
        S3BUF = c;
        while (!(S3CON & S3TI));	//等待发送成功
        S3CON &= ~S3TI;	  //清除发送中断标志
        return c;
    }
    

    我们只需要将这个putchar函数包含在工程中,然后初始化串口3,便可以利用printf打印串口了。

    展开全文
  • 新唐单片机printf函数

    2021-09-29 11:12:36
    新唐M480系列单片机printf函数难道只能用它内部的retarget.c文件来实现吗。我自己重定向了putc函数反现没有用?一下
  • 51单片机printf 为0

    2021-01-13 14:03:05
    在51单片机上使用printf函数、以下几点: 1. 无符号16位数格式符用%d或者%u,千万不能加字母“l”,否则会出错2. 32位数据格式符必须加字母“l”,否则会出错3. 8位数据格式符要加字母“b”,例如%bd、%bu等 ...
  • 在STM32F103C8T6单片机上,将printf函数重新映射到串口3上。可以通过串口3输出调试打印信息。
  • 官方printf函数一次只能定向一个串口,而通过自实现的printf可实现任意串口同时发送。 实用举例:myprintf(USART3, "num1 = %d\tnum2 = %f\r\n", num1,num2); (该程序较之前上传的版本效率更高)
  • 请问一下大佬,51单片机进入定时中断后,我想用按键关闭中断,但用EA=0类无法关闭,,进入定时中断后,如何关闭它
  • 51单片机 printf函数 调试程序

    千次阅读 2019-06-25 17:24:08
    方便调试51单片机程序流程;...(3)为何printf输出为串口。 (1)51单片机程序部分 #include <stdio.h> #include <reg51.h> void InitUART(void)//使用定时器1作为串口波特率发生器 { T...
  • PIC单片机printf()函数重定向

    千次阅读 2018-09-15 11:20:14
    基本信息: ...单片机:PIC18F66K22 下载器:PICKit3 一、串口初始化 /* 函数名:void USART1_Init( void ) 功能:使用的是串口1,串口初始化 */ void USART1_Init( void ) { TRISC6 = 1; ...
  • 51单片机的串口printf输出函数.rar
  • 51单片机printf

    2020-08-10 20:49:23
    我先在知道想要在51单片机使用printf有两种办法,一种是用库自己的printf,一种是写自己的printf,不过都很简单,我先介绍一下库的printf吧。
  • STC51单片机printf的用法

    千次阅读 2016-05-09 11:44:44
    今天用STC51系列的单片机写程序遇到一个问题,就是Printf函数的用法,并在这个上面颇费周折,才弄清楚用法和注意事项! 1.包含stdio.h这个头文件; 2.用Printf函数前要先关闭串口中断,可以在调用函数之后打开中断...
  • 单片机printf函数,串口重定向

    千次阅读 2018-03-19 15:27:38
    搜索fputc函数,将fputc函数中的串口配置修改成所应用的串口,然后就可以使用printf函数打印了
  • 利用51单片机C语言实现printf函数的功能,带PROTEUS仿真源文件,带源程序。
  • 51中printf使用注意 C51标准串口发送程序(已C8051F120为例,注意C8051F120特殊功能寄存器是分页的)
  • 昨天在群里面有一个网友提到使用printf为什么编译通过了,但是没有效果 。这里将我的笔记翻出来共享一下,这个实验本身没有太大的意义,主要是记录51单片机应该如何使用函数。实验名称:串口通信之单片机和PC计算...
  • 单片机中使用printf

    2021-05-21 10:47:04
    但是在单片机中没有控制台可以输出信息,但是我们可以将printf()输出到串口,连接串口工具后,在串口工具的界面中显示调试信息。下面分别以stm32 和 80C51作为例子来实现。2 80C51中使用printf1,首先是对要使用的...
  • 51单片机使用printf函数输出

    千次阅读 2022-02-27 20:38:34
    51单片机使用printf为什么编译通过了,但是没有效果 ? MCU型号:STC12C5A60S2 晶振 :11.0592MHZ 实验内容:利用单片机和PC机串口通信的 (晶振为11.0592MHZ)设置波特率为9600 第一个版本的代码如下**(不能正确...
  • 如题 stc单片机printf输出到1602
  • 51单片机实现scanf和printf

    热门讨论 2014-02-27 16:53:58
    51单片机实现scanf和printf函数,在需要格式化输出输入时使用,方便很多,不必在进行取余取整运算,而且输出格式自定义,跟windows下的使用方法一样。
  • 单边机编程中总会用到printf函数作为调试工具,编译器自带printf函数只能使用uart1,但是有时候有于硬件限制,实际的调试串口不一定是 uart1,所以我总结以下 2 种整改 printf函数的方法,使得 uart1,uart2,uart3...
  • 工程是keil2. 简单的利用C51单片机,实现了printf函数输出字符串,数字等。 找了好多资料,然后自己总结了下,实现了printf函数的应用。 有了printf函数,你就可以像VC中一样实现输出了。
  • STC单片机使用Printf

    2021-09-25 17:22:27
    #include "STC8Axx.h" #include "Uart1.h" ... //用于printf #include <stdarg.h> //用于vsprintf函数原型 bit bUart1Busy; bit bUart1ReceiveFinish = 0; //串口1接收完成标志 (1: 表.
  • **如下图,否则printf()无法输出。 void UartInit(void) //9600bps@22.1184MHz { PCON |= 0x80; //使能波特率倍速位SMOD SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x40; //定时器时钟1T模式 AUXR &...
  • 单片机printf函数重定向

    千次阅读 2015-05-23 23:42:00
    #include <reg51.h>#include <stdio.h>...//51单片机定义为char,如果是32位单片机就定义为int类型 #define _INTSIZEOF(x) ((sizeof(x) + sizeof(char) - 1) & ~(sizeof(char) - 1) )#define va_start(ap,v) (ap =
  • 实现的原理:就是找到printf 和scanf函数的输入/输出端的接口函数把它修改定向到串口。 /** @copyright Copyright(c)2014-2011 XXXX Co.,Ltd. All rights reserved. *******************************************...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,824
精华内容 7,529
关键字:

单片机printf