大小端序轉換


  在嵌入式開發中,經常碰到因端序使用不當導致的錯誤,故決定決定將工作中常見的轉序函數進行梳理,一是為了避免犯同樣的錯誤,二是為了以后方便查詢。本文分為四個部分:1、什么是大小端序;2、大小端序數據相互轉換函數;3、應用場景;4、使用總結。

  1、什么是大小端序

  大端模式:是指數據的高字節保存在內存的低地址中,而數據的低字節保存在內存的高地址中。

  小端模式:是指數據的高字節保存在內存的高地址中,而數據的低字節保存在內存的低地址中。

  現在,以一個unsigned int整型數據0x12345678為例,其大端序、小端序的存儲內容如圖所示。

  

  2、大小端序數據相互轉換函數

  a)將unsigned char數組轉換成“大端序”整數;

/*
*    Function:        ConverseArrayToBeUI
*    Description:    將無符號字符數組數據轉換成“大端序”整數
*    Parameter:        srcArray    --[in]    源數組數據
*                    desBeData    --[out]    目標“大端序”整數
*    Return            0    成功
*                    非0    失敗
*    Note:            
*    Other:
*/
int MULCONVERSE_CALL ConverseArrayToBeUI(unsigned char *srcArray,unsigned int *desBeData)
{
    if (srcArray == NULL_POINT || desBeData == NULL_POINT)
    {
        return ERR_NULL_POINT;
    }
    *desBeData = (unsigned int)(srcArray[0]<<24) + (unsigned int)(srcArray[1]<<16) + 
                    (unsigned int)(srcArray[2]<<8) + (unsigned int)srcArray[3];
    return _SUCCESS;
}

  b)將unsigned char數組轉換成“小端序”整數;

/*
*    Function:        ConverseArrayToLeUI
*    Description:    將無符號字符數組數據轉換成“小端序”整數
*    Parameter:        srcArray    --[in]    源數組數據
*                    desLeData    --[out]    目標“小端序”整數
*    Return            0    成功
*                    非0    失敗
*    Note:            
*    Other:
*/
int MULCONVERSE_CALL ConverseArrayToLeUI(unsigned char *srcArray,unsigned int *desLeData)
{
    if (srcArray == NULL_POINT || desLeData == NULL_POINT)
    {
        return ERR_NULL_POINT;
    }
    *desLeData = (unsigned int)(srcArray[3]<<24) + (unsigned int)(srcArray[2]<<16) + 
                    (unsigned int)(srcArray[1]<<8) + (unsigned int)srcArray[0];
    return _SUCCESS;
}

  c)將整數按照“大端序”格式存儲在數組中;

/*
*    Function:        ConverseUItoBeArray
*    Description:    將無符號整數轉換成“大端序”存儲的無符號字符數組
*    Parameter:        srcData        --[in]    源整數
*                    desBeArray    --[out]    目標“大端序”存儲的數組數據
*    Return            0    成功
*                    非0    失敗
*    Note:            
*    Other:
*/
int MULCONVERSE_CALL ConverseUItoBeArray(unsigned int srcData,unsigned char *desBeArray)
{
    if (desBeArray == NULL_POINT)
    {
        return ERR_NULL_POINT;
    }
    desBeArray[0] = (unsigned char)(srcData>>24);
    desBeArray[1] = (unsigned char)(srcData>>16);
    desBeArray[2] = (unsigned char)(srcData>>8);
    desBeArray[3] = (unsigned char)srcData;
    return _SUCCESS;
}

  d)將整數按照“小端序”格式存儲在數組中。

/*
*    Function:        ConverseUItoLeArray
*    Description:    將無符號整數轉換成“小端序”存儲的無符號字符數組
*    Parameter:        srcData        --[in]    源整數
*                    desLeArray    --[out]    目標“小端序”存儲的數組數據
*    Return            0    成功
*                    非0    失敗
*    Note:            
*    Other:
*/
int MULCONVERSE_CALL ConverseUItoLeArray(unsigned int srcData,unsigned char *desLeArray)
{
    if (desLeArray == NULL_POINT)
    {
        return ERR_NULL_POINT;
    }
    desLeArray[3] = (unsigned char)(srcData>>24);
    desLeArray[2] = (unsigned char)(srcData>>16);
    desLeArray[1] = (unsigned char)(srcData>>8);
    desLeArray[0] = (unsigned char)srcData;
    return _SUCCESS;
}

  3、應用場景

  PC(小端序)向芯片(大端序)發送數據

  假設PC產生一個整數數值0x00000001,經通信接口(比如串口)向芯片發送數據時,按照一次發一字節的方式傳輸數據,那么此時芯片就會收到4字節數據,其內容按照地址從低到高排序為0x01,0x00,0x00,0x00,那么芯片就會認為自己收到的整數數值為0x01000000。

  此時,兩個硬件平台就會因為大小端的不同造成數據收發錯誤,此時解決的方法有兩種:1、PC發送數據之前,通過轉換函數ConverseUItoBeArray,將整數數值0x00000001轉換成[00,00,00,01]字符數組,然后經通信接口發給芯片;2、芯片接收到4字節數據之后,通過函數ConverseArrayToLeUI,將[01,00,00,00]轉換成整數0x00000001。

 

  4、使用總結

  (1)不同的硬件平台如果采用同一種類型的端序,計算/使用時無需轉序;

  (2)不同的硬件平台如果采用不同類型的的端序,但傳輸的字符數組“無需”轉換成多字節基本類型數據(如int,double,float)時,計算/使用時無需轉序;

  (3)不同的硬件平台如果采用不同類型的的端序,但傳輸的字符數組“需要”轉換成多字節基本類型數據(如int,double,float)時,計算/使用時需要轉序;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM