CAN通信的時候,每一幀的大小是有固定限制的沪铭,所以為了將盡可能多的數(shù)據(jù)通過一幀frame傳輸出去壮池,都會將數(shù)據(jù)盡量壓縮到一個frame里面。比如受信的時候杀怠,有的數(shù)據(jù)在代碼里面是用char存儲的椰憋,但是內(nèi)容可能僅僅是0和1。這樣的數(shù)據(jù)在往frame里面送的時候可能僅僅1個bit就足夠了赔退。針對這樣的轉(zhuǎn)換橙依,可以使用下面函數(shù)來實現(xiàn)。這個函數(shù)的概要就是從Buffer所表示的某個frame里面硕旗,從StartIndex的BitPosition開始的長度為size的數(shù)據(jù)給截取出來賦值給某個變量窗骑。?
uint32 ExtractData(uint8 Buffer[], uint8 StartIndex, uint8 BitPosition, uint8 Size){ uint8 TempData; uint32 RstData; uint8 TempSize; RstData = 0x00; while ((BitPosition + 1) < Size) { /* Calculate size in 1 byte */ TempSize = BitPosition + 1; /* Extract Data in 1 byte */ TempData = ExtractByteData(Buffer[StartIndex], BitPosition, TempSize); /* Update Parameter */ Size = Size - TempSize; RstData = RstData + (TempData << Size); BitPosition = 7; StartIndex++; } /* Extract Data */ RstData = RstData + ExtractByteData(Buffer[StartIndex], BitPosition, Size); return?(RstData);}
其中ExtractByteData函數(shù)的處理如下uint8, ExtractByteData(uint8 Data, uint8 BitPosition, uint8 Size){ uint8 Value; uint8 Mask; uint8 Shift; if ((0 < Size) && (Size <= 8)) { Shift = BitPosition - (Size - 1); Value = Data >> Shift; Mask = BIT_MASK(Size); Value = Value & Mask; } else if (Size == 0) { Value = 0x00; } else { Value = Data; } return (Value);}BIT_MASK的定義為 #define BIT_MASK(Size) ((1u << (Size)) - 1)下面是將數(shù)據(jù)壓縮到一個frame里面的操作。這個例子里面數(shù)據(jù)a是一個uint32的數(shù)據(jù)漆枚,想將它里面的值放到frame的4到6里面慧域,4和5占8位,6占2位浪读。每個byte里面都是從第7位開頭昔榴。DataBuf[4] |= (uint8)(((a / 0x400) & BIT_MASK(8)) << BIT_SHIFT(7,8));DataBuf[5] |= (uint8)(((a / 0x4) & BIT_MASK(8)) << BIT_SHIFT(7,8));DataBuf[6] |= (uint8)(((a) & BIT_MASK(2)) << BIT_SHIFT(7,2));BIT_SHIFT的定義是 BIT_SHIFT(StartPosition, Size) (uint8)((StartPosition) - ((Size) - 1))
//將val的值放到array的pos位置開始的len長度的空間
SetBits(uint8 array[], uint32 pos, uint32 len, uint32 val)
{
? ? uint32 byte_pos = pos / 8;
? ? /* top zone */
? ? if ((pos % 8) > 0)
? ? {
? ? ? ? uint32 rem_bits = 8 - (pos % 8);
? ? ? ? uint32 tlen = ((len < rem_bits) ? len : rem_bits);
? ? ? ? uint32 off = rem_bits - tlen;
? ? ? ? len -= tlen;
? ? ? ? array[byte_pos] &= (uint8)~((uint32)BIT_MASK(tlen) << off);
? ? ? ? array[byte_pos] |= (uint8)((val >> len) << off);
? ? ? ? byte_pos += 1;
? ? }
? ? /* byte copy zone */
? ? while (len >= 8)
? ? {
? ? ? ? len -= 8;
? ? ? ? array[byte_pos] = (uint8)(val >> len);
? ? ? ? byte_pos += 1;
? ? }
? ? /* last zone */
? ? if (len > 0)
? ? {
? ? ? ? uint32 off = 8 - len;
? ? ? ? array[byte_pos] &= (uint8)(~(BIT_MASK(len) << off));
? ? ? ? array[byte_pos] |= (uint8)(((uint32)val & BIT_MASK(len)) << off);
? ? }
}