关闭

stm32 printf的实现

458人阅读 评论(0) 收藏 举报
分类:

嵌入式系统开发中,常常使用串口将重要的数据或者字符信息打印到PC,为系统的调试带来了很大的便利。本文简单介绍一下printf在stm32上的实现,当然也不仅限于stm32,只要把串口发送函数稍加改动就可以移植其他任何微控制器环境上。

提到printf,首先简单介绍一下可变参数的实现va函数:

va_list arg_ptr;

void va_start( va_list arg_ptr, prev_param ); 
type va_arg( va_list arg_ptr, type ); 
void va_end( va_list arg_ptr );

首先在函数里定义一个va_list型的变量,这里是arg_ptr,这个变量是指向参数的指针。然后使用va_start使arg_ptr指针指向prev_param的下一位,然后使用va_args取出从arg_ptr开始的type类型长度的数据,并返回这个数据,最后使用va_end结束可变参数的获取。

代码:

#include <stdarg.h>
#include "Stm32f10x_conf.h"
#include "com.h"

int itoa(int num, char *str, int radix)
{
        char string[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char* ptr = str;
        int temp;
        int i;
        int j;        

        if (num==0)
        {
                *ptr++ = 0x30;
                *ptr = 0;
                return 1;
        }
        if(num < 0)
        {
            *ptr++ = '-';
            num *= -1;
        }
        while (num)
        {
                *ptr++ = string[num % radix];
                num /= radix;

                if (num < radix)
                {
                        *ptr++ = string[num];
                        *ptr = '\0';
                        break;
                }
        }

        j = ptr - str - 1;

        for (i = 0; i < (ptr - str) / 2; i++)
        {
                temp = str[i];
                str[i] = str[j];
                str[j--] = temp;
        }


        return (int)(ptr - str);
}




void Uart_Config()
{
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);    

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     
    GPIO_Init(GPIOA, &GPIO_InitStructure);             //PA9

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;         //USART1 RX
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
    GPIO_Init(GPIOA, &GPIO_InitStructure);             //PA10

    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);

    USART_Cmd(USART1, ENABLE);

    return;
}

void ComPrint(u8 *Data,...)
{
    const char *s;
    int d;
    char buf[16];
    va_list ap;
    va_start(ap, Data);

    while(*Data!=0)
    {                          
        if(*Data == '\n')
        {
            USART_SendData(USART1, 0x0d);
            while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
            USART_SendData(USART1, 0x0a);
            while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
            Data++;
        }
        else if(*Data=='%')
        {
            switch (*++Data){
            case 's':
                s = va_arg(ap, const char *);
                for ( ; *s; s++) {
                    USART_SendData(USART1,*s);
                    while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
                }
                Data++;
                break;
            case 'd':
                d = va_arg(ap, int);
                itoa(d, buf, 10);
                for (s = buf; *s; s++) {
                    USART_SendData(USART1,*s);
                    while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
                }
                Data++;
                break;
            case 'x':
                d = va_arg(ap, int);
                itoa(d, buf, 16);
                for (s = buf; *s; s++) {
                    USART_SendData(USART1,*s);
                    while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
                }
                Data++;
                break;
            default:
                Data++;
                break;
            }  
        }
        else
        {
            USART_SendData(USART1, *Data++);
            while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
        }
    }
}


/***************************************************************
*
*
*
***************************************************************/
void assert_debug(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,\ */
    ComPrint("Wrong parameters value: file %s on line %d\r\n", file, line);


  /* Infinite loop */
    while (1)
    {
    }
}




0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

STM32 Printf函数实现方法

今天调试了stm32f407的ADC,一切顺利,然而用串口发送ADC结果时都是16进制数,看着很不爽。于是打算用用牛B的“printf”函数,按照以前的做法,在main文件中添加了“stdio.h”,...
  • wocao1226
  • wocao1226
  • 2014-01-15 17:17
  • 3099

STM32-串口通信printf重定向

前言:平时我们进行c语言编程的时候会经常用到printf函数进行打印输出,来调试代码。可是这个printf函数C库已经帮我们实现好了,通常只需要直接调用即可,但是如果在一个新的开发平台,如果库没有帮我...
  • zouleideboke
  • zouleideboke
  • 2017-06-11 19:56
  • 429

STM32的printf函数重定向

在前面学习了STM32的串口编程,通过USART1向计算机的串口调试助手打印数据,或者接收计算机串口调试助手的数据,接下来我们可以实现STM32工程上的printf()函数了,方便用于程序开发中调试信...
  • qq_29344757
  • qq_29344757
  • 2017-07-19 12:21
  • 715

STM32高级开发(12)-在GCC中使用printf打印串口数据

在大家使用keil或是iar开发stm32等arm芯片的时候,想来最不陌生的就是使用print通过串口输出一些数据,用来调试或是其他作用。但是要明确的是由于keil iar gcc 他们使用的标准C语...
  • zhengyangliu123
  • zhengyangliu123
  • 2017-02-10 11:36
  • 1658

stm32之printf重定向

在程序的调试过程中,除了那些高大上的调试手段外,printf无疑是我们最熟悉最顺手的调试方法。通过使用printf,我们可以很方便很直观的获取当前程序的运行状态。 printf()函数是格式...
  • leon0820
  • leon0820
  • 2014-07-19 15:56
  • 1211

stm32 printf函数重定向

#include "stm32f10x.h" #include "stdio.h" void RCC_Configuration(void);//首先设置系统时钟为8MHZ void GPIO_C...
  • dxuehui
  • dxuehui
  • 2016-11-09 23:12
  • 598

STM32+Keil 如何使用printf函数?

【lanmanck原创】 Keil不支持Host-semi机制,即不支持直接在IDE打印字符串。 那么只能通过程序向硬件串口发数据了,这样调用的时候用自定义的函数即可,也很方便,例如: vo...
  • lanmanck
  • lanmanck
  • 2013-12-19 11:07
  • 25611

stm32实现printf重定向到LCD显示屏

转自:http://www.51hei.com/bbs/dpj-35962-1.html 嘿嘿,学习stm32已经有一段时间了。以前纠结过一个问题,(USART)串口的可变参数问题,查找C语言的书终...
  • u012252959
  • u012252959
  • 2016-09-19 11:25
  • 920

通过串口实现printf和scanf函数

转自  草根老师博客(程姚根) 在做裸板开发时,常常需要通过输出或者通过串口输入一些信息。 在有操作系统机器上,我们很少关心输入和输出的问题。因为有很多现成的库函数供我们调用。在做裸板开发时,可...
  • fillthesky
  • fillthesky
  • 2016-08-13 16:16
  • 1088

关于stm32中printf函数重定向问题

学习stm32过程中,对printf函数进行了重定向,但是能够在串口调试助手中显示出来,并且debug不能全速运行,printf函数阻碍了程序的运行。 后来求教了度娘。 标准库函数的默认输出设备是...
  • yy105419
  • yy105419
  • 2017-01-24 20:33
  • 260
    最新评论
    个人资料
    • 访问:65850次
    • 积分:154
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:111篇
    • 译文:1篇
    • 评论:3条