STM32
直播中

CDCNKA

8年用户 1231经验值
擅长:385288
私信 关注
[问答]

如何解决移植MPU6050的DMP库遇见的问题?

如何解决移植MPU6050的DMP库遇见的问题?

回帖(1)

王琴

2021-12-2 09:31:49

引入:最近在移植MPU6050的DMP库的时候遇到了许多问题,其驱动代码中有关打印日志的部分让我印象深刻,他的传参格式和printf很像,包括在做其他驱动移植参考别人的移植代码时,别人的串口输出函数也是用的printf关键字。这种传参方式在参数格式多变,数量多变的情况下着实有用。


这里我们先来了解一下传统printf函数的代码。。


int printf(const char *format, ...)
{
    va_list L;                    //生成栈
    int count=0;        //用于记录参数个数
    va_start(L,format);//指向栈中的第一个数据 (获取首指针)
    count=vprintf(format,L);//轮询打印
    va_end(L);                  //结束栈(清除)
    return count;
}
从这段代码中可以知道:


不定参函数的定义格式 : 类型   函数名(参数,...){代码段;}
代码段是一堆用于处理参数的宏定义和一个返回值(这里用于返回参数个数)组成。
对于不定参函数最重要的宏命令有这三个:va_list , va_start , va_end 。
va_list定义一个用于存放不定参数的列表。
va_start指向首指针
va_end结束列表,释放内存

除去这三个,还有一些就是用于处理列表的函数了。比如,va_arg,vsprintf等。举个例子,试试下面这个函数。


int sum(int number,...)
{
        int s=0;
        va_list L;
        va_start(L,number);
        while( number--)
                s=s+va_arg(L,int);
        va_end(L);
        return s;
}
不难看出这是一个任意个数整数求和的函数。我们发现这里的形参number是一个整型,指的是后面参数的个数。结合printf那个例子中的format,我们可以得出:不定参函数必须传入至少一个形参,用于修饰后面的不定参数。


那么在STM32中,则有


int USART_Printf(const char *format,...)
{
        __va_list L;            
        char str[64];            //用于存放输出结果
        __va_start(L,format);   
        vsprintf(str,format,L);  //格式转换
        Usart_SendString(USART1,str);//默认使用串口1
        __va_end(L);
}

int OLED_Printf(const char *format,...)
{
        __va_list L;
        char str[64];            //用于存放输出结果
        __va_start(L,format);
        vsprintf(str,format,L);  //格式转换  
        OLED_ShowString(0,0,str,20);//默认打印位置(x=0,y=0,str,字号20)
        __va_end(L);

}
vsprintf函数可以参考sprintf,更多关于va_list数据格式的操作函数可以自己去标准库里找。











举报

更多回帖

发帖
×
20
完善资料,
赚取积分