嵌入式如何使用printf打印

  我们在程序中使用printf把需要打印的信息打印到控制台上,那么在嵌入式中如何用printf来输出打印信息呢?

  有两种方法:

  其一,把fput()函数重新定义

  其二,重新定义一个类似printf的函数

  首先,介绍把fput()重新定义的方法

 1 struct __FILE
 2 {
 3     int handle;
 4 };
 5 FILE __stdout;
 6 FILE __stdin;
 7
 8 int fputc(int ch, FILE * p_file)
 9 {
10     assert_param(p_file);
11
12         HAL_UART_Transmit(&UartDebugHandle, (uint8_t *)&ch, 1, 0xFFFF);
13
14     return ch;
15 }

  因为printf()会调用fputc()函数向控制台发数据,我们将fputc()重定义,在该函数里边用串口发数据,所以当我们调用printf()时,就可以通过串口把数据发出去。

  接下来介绍第二种方法:

 1 #include <stdarg.h>
 2 #include <stdio.h>
 3
 4 #define MAX_LENGTH 200
 5 static uint8_t debug_buffer[MAX_LENGTH] = {0};
 6
 7 void test_printf(const char *fmt, ...)
 8 {
 9     va_list vlist;
10
11     va_start(vlist, fmt);
12     vsnprintf(debug_buffer, MAX_LENGTH, fmt, vlist);
13     HAL_UART_Transmit_IT(&UartDebugHandle, (uint8_t*)debug_buffer,strlen(debug_buffer));
14     va_end(vlist);
15 }
16 然后,就可以调用test_printf()往外发数据了。
17 eg:int num = 100;
18 test_printf(“This is test num: %d”,num);

注:

  1、在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表。

eg:void test_printf(const char *fmt, ...)

  2、函数参数的传递原理

  我们知道,函数的参数再内存中是存在栈中的,形参的存入顺序是从右向左存入的,void func(int x, float y, long z),在调用函数时,形参入栈的顺序是z > y >x,即z先入栈。

  栈是从上往下增长的,即从内存地址高的位置开始增长,往内存地址低的方向上增长。因此,我们只要知道形参中任一变量的内存地址,就可以得到其它变量的内存地址。

  3、介绍下test_printf()的实现

  在<stdarg.h>中定义了如下:

  typedef char * va_list;

  void va_start ( va_list ap, prev_param );

  void va_end ( va_list ap );

  void test_printf(const char *fmt, ...)

  {

    //定义指针vlist

  va_list vlist;

    //让vlist指向形参的第一个变量

    va_start(vlist, fmt);

    //把fmt和不定长的参数(vlist指向参数列表)复制到debug_buffer中

    vsnprintf(debug_buffer, MAX_LENGTH, fmt, vlist);

    HAL_UART_Transmit_IT(&UartDebugHandle, (uint8_t*)debug_buffer, strlen(debug_buffer));

    //在使用完指针之后,需要把指针关掉,以防出现危险。

     va_end(vlist);

   }

时间: 2024-10-10 07:43:14

嵌入式如何使用printf打印的相关文章

IAR 的printf打印问题

IAR 软件自己的库函数不能实现printf打印浮点数的功能,但是打印整型变量是可以的 可以用整型实现printf打印浮点数的功能

STM32M CUBE实现printf打印调试信息以及实现单字节接收

在写单片机程序时我们一般喜欢使用printf来通过串口打印调试信息,但这个函数是不可以直接使用的,必须做点对库函数的改动. 详细工程下载地址: http://download.csdn.net/detail/liucheng5037/8847961 STM32M CUBE是ST官方提供的库以及初始化工具,很好很强大,但是在UART方面值提供了如下函数: HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *

[misc]如何在嵌入式平台使用printf功能

转自:http://www.cnblogs.com/liu_xf/archive/2011/04/14/2015726.html 摘要: 当我们在调试代码时,通常需要将程序中的某个变量打印至PC机上,来判断我们的程序是否按预期的运行,printf函数很好的做到了这一点,它能直接以字符的方式输出变量名和变量的值,这样使输出的信息很直观:但printf函数在使用时,不仅仅要初始化串口,还需要其它的一些设置或者要调用其它的一些函数,否则printf函数将不能按我们想要的方式执行. 由于不同的编译器st

C语言练习-printf打印图形

利用printf函数打印出正方形,正三角,倒三角,平行四边形,菱形 #include <stdio.h> #include <stdlib.h> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ void PRINTF_square (int n); void PRINTF_Etriangle (int n);

串口发送与printf打印

那么只要是有串口的单片机,调用一下printf()就可以打印信息了吗?还没那么简单,单片机并不能猜透你的意图,你需要告诉它往哪里printf,通过下面的fputc()函数来实现.fputc()是printf()的底层函数,需要把它改装一番,让它把要打印的数据发送到串口上去. 参考:https://blog.csdn.net/qq_26904271/article/details/80113740 原文地址:https://www.cnblogs.com/make-big-money/p/1260

51学习笔记之使用printf打印串口数据

#include<reg51.h> #include<stdio.h> void UartInit(void) //初始化波特率为9600 { SCON=0x50; TMOD=0x20; TCON=0x40; TH1=0xfd; TI=1; TR1=1; } void main() { UartInit(); printf("hello world"); //输出一次数据 while(1); }

geany写C语言,printf打印中文时显示乱码

原因 geany设置了编码格式为utf8 运行时显示出的cmd窗口编码格式为GBK 解决方法 打开cmd窗口,使用" chcp 65001 " 命令,临时设置cmd窗口显示为utf编码格式,然后手工运行程序即可正常显示. 永久修改cmd窗口显示为utf8编码格式. 参考:windows系统修改cmd窗口utf-8编码格式 原文地址:https://www.cnblogs.com/sfriend/p/10806983.html

Python直接调用C库的printf()函数打印一条消息

github博客传送门 csdn博客传送门 话不多说直接上代码 # 直接从 C 库中调用 printf()函数打印一条消息 # Windows 中的 C 库位于 C:\WINDOWS\system32\msvcrt.dll,Linux 中的 C 库位于/lib/libc.so.6 import ctypes # 导入ctypes包 # msvcrt = ctypes.cdll.LoadLibrary("C:\WINDOWS\system32\msvcrt.dll") # 等同于msvc

printk和printf的区别

内核使用printk()打印! 应用层使用printf()打印! &&& 大部分常用的C库函数在Linux内核中都已经得到了实现.在所有没有实现的函数中,最著名的就数printf()函数了.内核代码虽然无法调用  printf()函数,但它可以调用printk()函数.printk()函数负责把格式化好的字符串拷贝到内核日志缓冲上,这样syslog程序就可  以通过读取该缓冲区来获取内核信息.printk()的用法很像printf(): & printk("Hel