关闭

stm32 printf的实现

414人阅读 评论(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网站的观点或立场
    最新评论
    个人资料
    • 访问:52486次
    • 积分:29
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:111篇
    • 译文:1篇
    • 评论:2条