2015-06-09 102 views
4

我知道有很多这方面的例子,但是他们都没有工作。 PPTR是一个指向这种类型将32位长分成4个字节

typedef struct 
{ 
    TIMESTAMP_TYPE oTimeStamp; 
    ASSERT_ID_TYPE ucAssertID; 
    Int16 iData1; 
    Int16 iData2; 
    UInt16 uiChecksum; 
} 
LOG_ENTRY_TYPE; 

,我出列,我的日志时,有一个我想关店到EEEPROM的临时日志。
oTimestamp的类型是

typedef struct 
{ 
    UInt32 ulSecond; 
    UInt16 usMilliSecond; 
    UInt16 usPowerCycleCount; 

} 
    TIMESTAMP_TYPE; 

所有其他的访问,甚至可用于毫秒写入工作,但我不能细分为4个字节秒时间戳值。

这是我曾尝试(很明显,只有一个版本的注释去掉了):

UChar tmpByteHigh; 
UChar tmpByteLow; 

//Attempt1 
tmpByteHigh = (pPtr->oTimeStamp.ulSecond >> 24) & 0x000000FF; 
SPIwrite(tmpByteHigh); 
tmpByteLow = (pPtr->oTimeStamp.ulSecond >> 16) & 0x000000FF; 
SPIwrite(tmpByteLow); 
tmpByteHigh = (pPtr->oTimeStamp.ulSecond >> 8) & 0x000000FF; 
SPIwrite(tmpByteHigh); 
tmpByteLow = (pPtr->oTimeStamp.ulSecond) & 0x000000FF; 
SPIwrite(tmpByteLow); 

//Attempt 2 
tmpByteHigh = (pPtr->oTimeStamp.ulSecond & 0xFF000000UL) >> 24; 
SPIwrite(tmpByteHigh); 
tmpByteLow = (pPtr->oTimeStamp.ulSecond & 0x00FF0000UL) >> 16; 
SPIwrite(tmpByteLow); 
tmpByteHigh = (pPtr->oTimeStamp.ulSecond & 0x0000FF00UL) >> 8; 
SPIwrite(tmpByteHigh); 
tmpByteLow = (pPtr->oTimeStamp.ulSecond) & 0x000000FFUL; 
SPIwrite(tmpByteLow); 


//Attempt 3 
//get msw from 32 bit value and write the 2 msB from it 
tmpWord = (pPtr->oTimeStamp.ulSecond >> 16) & 0x0000FFFF; 
tmpByteHigh = (tmpWord >> 8) & 0x00FF; 
SPIwrite(tmpByteHigh); 
tmpByteLow = tmpWord & 0x00FF; 
SPIwrite(tmpByteLow); 
//get lsw from 32 bit value and write the 2 lsB from it 
tmpWord = pPtr->oTimeStamp.ulSecond & 0x0000FFFF; 
tmpByteHigh = (tmpWord >> 8) & 0x00FF; 
SPIwrite(tmpByteHigh); 
tmpByteLow = tmpWord & 0x00FF; 
SPIwrite(tmpByteLow); 


//Attempt 4 
UChar* myPointer = (UChar*)&pPtr->oTimeStamp.ulSecond; 
UChar myArray[4]; 
myArray[0]=myPointer[0]; 
myArray[1]=myPointer[1]; 
myArray[2]=myPointer[2]; 
myArray[3]=myPointer[3]; 
SPIwrite(myArray[0]); 
SPIwrite(myArray[1]); 
SPIwrite(myArray[2]); 
SPIwrite(myArray[3]); 

每一次我得到0×00 0×00 0×00 0x80的送过来SPI。有什么想法吗?对我来说简单我不是一个优秀的程序员。

+0

...什么是预期输出? – user35443

+1

想法?是。你的'pPtr-> oTimeStamp.ulSecond'中有错误的数据。或者'SPIwrite'中的错误。因为转换代码很好。 –

+1

也许'pPtr-> oTimeStamp.ulSecond'确实等于'0x80000000'?你用4种不同的方式证明了这一点。似乎是一个非常有力的证据 – anatolyg

回答

2

使用union,你可以以多种方式访问​​相同的数据:

typedef union 
{ 
    struct { 
     UInt32 ulSecond; 
     UInt16 usMilliSecond; 
     UInt16 usPowerCycleCount; 
    }; 
    UInt8 byte[8]; 
} 
TIMESTAMP_TYPE; 

int main() { 
    TIMESTAMP_TYPE T; 
    T.ulSecond = 1; 
    T.usMilliSecond = 2; 
    T.usPowerCycleCount = 3; 
    printf("sizeof(T) = %ld\n", sizeof(T)); 
    for(int i = 0; i < 8; i++) 
     printf("T[%d] = 0x%2.2X\n", i, T.byte[i]); 
    return 0; 
} 

打印:

sizeof(T) = 8 
T[0] = 0x01 
T[1] = 0x00 
T[2] = 0x00 
T[3] = 0x00 
T[4] = 0x02 
T[5] = 0x00 
T[6] = 0x03 
T[7] = 0x00 

要注意的是字节数组有本地endianness。如果这不是所需的字节顺序,你将不得不交换字节。

+0

谢谢,我会继续朝着工会的方向前进。感谢您的帮助,试图upvote你,但没有足够高的声誉......再次感谢 – lbeh

+0

您忽略多字节值的期望endianness。 – nategoose

+0

是的。这只是给你的本地排序。如果本地排序不是所需的,则需要转换 – fferri