首页 > 编程知识 正文

比特位和字节转换

时间:2023-05-03 11:49:39 阅读:285614 作者:2540

先说一下应用场合,在LED点阵显示屏中,为了节省flash空间,常用一个bit位来标记哪个灯是否点亮。为了做出比较炫的效果,比如16 * 16像素gif动画边边移动边跳跃。就应用到该思想。

双字节是16bit位,数组的bit位是数组长度乘以8(类型指的是uint8_t),比如uint8_t a[5]长度则是5 * 8 = 40。该函数的思想就是这双字节的16bit位在在数组a[5]中40bit位中移动。当然16bit位在数组中可以移出部分或者移出全部bit位。如下图所示三个中情况。

代码如下所示:

#include

typedef unsigned char uint8_t;

typedef unsigned short uint16_t;

#define VALID_LENGTH16//双字节中的有效长度

/********************************************************************************

p:数组指针

n:数组的有效长度

c:需要移动的双字节

matrixStartPos:游标需要在数组的中bit位中的起始位置,比如26,则相当于起始位置指向

数组下标为3 = 26 / 8,bit为5 = 7 - 26 % 8的那个地方。

doubleByteStartPos:指向双字节的bit位置范围为(0~15),该变量后面会移动

width:从双字节中doubleByteStartPos起始位置开始,截取的bit位的个数

********************************************************************************/

void DoubleByteShiftInMatrix(uint8_t *p, uint8_t n, uint16_t c, uint16_t matrixStartPos, uint8_t doubleByteStartPos, uint8_t width)

{

uint16_t matrix[] = {0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,

0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff};

uint8_t startBytePos = matrixStartPos / 8;//需要覆盖的首字节

uint8_t remainBits= 8 - matrixStartPos % 8;//指需要覆盖的首字节中剩余多少bit位可以被覆盖

uint8_t count = 0;//计算当前已经覆盖了多少bit位

while (count < width)//当已经覆盖的bit位小于字节的宽度,覆盖仍需继续

{

if (remainBits >= width - count)//当前字节剩余的bit位个数大于等于剩余需要覆盖的bit个数时,标志着覆盖进入尾声

{

p[startBytePos] &= ~(matrix[width - count -1 ] << (remainBits + count - width));//覆盖之前把当前的相对应bit位清零,下一行则表示对相对应的bit进行填充

p[startBytePos] |= (((c >> (VALID_LENGTH - doubleByteStartPos - width + count)) & matrix[width - count - 1]) << (remainBits + count - width));

count = width;//这个地方其本质的函数是count = count + (width - count);所以可以简化成了这样,也可以用break

}

else

{

p[startBytePos] &= ~matrix[remainBits - 1];//覆盖之前把相对应的bit位清零,下一行则是从双字节的“起始位置”截图remainBits长度填充当前数组剩余的remainBits位

p[startBytePos] |= ((c >> (VALID_LENGTH - doubleByteStartPos - remainBits)) & matrix[remainBits - 1]);

count += remainBits;//当前回合已经填充了remainBits的长度,进行统计

doubleByteStartPos += remainBits;//填充了remainBits长度后,双字节的起始位置也进行往后移动

startBytePos++;//填充完了一个字节,准备填充下一个字节

remainBits = 8;//新字节剩余填充位置为8

}

}

}

int main()

{

uint8_t p[] = {0x00, 0x00, 0x00, 0x00, 0x00};

int i = 0;

DoubleByteShiftInMatrix(p, 5, 0xffff, 38, 14, 2);

for (; i<5; i++)

{

printf("%d=%02xrn", i, p[i]);

}

return 0;

}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。