连续一段内存设置bit位的一种方法

来源:互联网 发布:台湾赖是什么软件 编辑:程序博客网 时间:2024/06/07 03:01
</pre><p>今天在看modbus通信的时候,发现一种比较好的设置一段连续内存bit位的方法。</p><p>两个函数 xMBUtilGetBits 和 xMBUTilSetBits。</p><p><pre name="code" class="cpp">UCHAR xMBUtilGetBits(UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits) {  USHORT usWordBuf;  USHORT usMask;  USHORT usByteOffset;  USHORT usNPreBits;  /* Calculate byte offset for first byte containing the bit values starting   * at usBitOffset. */  usByteOffset = (USHORT) ((usBitOffset) / BITS_UCHAR);  /* How many bits precede our bits to set. */  usNPreBits = (USHORT) (usBitOffset - usByteOffset * BITS_UCHAR);  /* Prepare a mask for setting the new bits. */  usMask = (USHORT) ((1 << (USHORT) ucNBits) - 1);  /* copy bits into temporary storage. */  usWordBuf = ucByteBuf[usByteOffset];  usWordBuf |= ucByteBuf[usByteOffset + 1] << BITS_UCHAR;  /* throw away unneeded bits. */  usWordBuf >>= usNPreBits;  /* mask away bits above the requested bitfield. */  usWordBuf &= usMask;  return (UCHAR) usWordBuf;}void xMBUtilSetBits(UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits,UCHAR ucValue){  USHORT usWordBuf;  USHORT usMask;  USHORT usByteOffset;  USHORT usNPreBits;  USHORT usValue = ucValue;  assert( ucNBits <= 8);  assert( ( size_t )BITS_UCHAR == sizeof( UCHAR ) * 8);  /* Calculate byte offset for first byte containing the bit values starting   * at usBitOffset. */  usByteOffset = (USHORT) ((usBitOffset) / BITS_UCHAR); //usByteOffset    /* How many bits precede our bits to set. */  usNPreBits = (USHORT) (usBitOffset - usByteOffset * BITS_UCHAR); //usNpreBits  /* Move bit field into position over bits to set */  usValue <<= usNPreBits; //MoveValue over bits to set  /* Prepare a mask for setting the new bits. */  usMask = (USHORT) ((1 << (USHORT) ucNBits) - 1); //  usMask <<= usBitOffset - usByteOffset * BITS_UCHAR;  /* copy bits into temporary storage. */  usWordBuf = ucByteBuf[usByteOffset];  usWordBuf |= ucByteBuf[usByteOffset + 1] << BITS_UCHAR;  /* Zero out bit field bits and then or value bits into them. */  usWordBuf = (USHORT) ((usWordBuf & (~usMask)) | usValue);  /* move bits back into storage */  ucByteBuf[usByteOffset] = (UCHAR) (usWordBuf & 0xFF);  ucByteBuf[usByteOffset + 1] = (UCHAR) (usWordBuf >> BITS_UCHAR);}
对一大块内存需要设定特殊位置的bit还是比较好的,不过是以字节对齐的方式

xMBUtilGetBits函数:

xMBUtilSetBits 函数

parameter:

UCHAR *ucByteBuf

USHORT usBitOffset

UCHAR ucNBits

UCHAR ucValue

ucByteBuf:需要设置位的数据内存

usBitOffset: 偏移从第0位开始的偏移量

ucNBits:  需要设置位的位置MASK

ucValue: 设置值

UCHAR dataBuf[4]={0xff,0xfc,0x00,0x00};

    xMBUtilSetBits(dataBuf,0, 8,0x00);

    xMBUtilSetBits(dataBuf,8,1,0x01);

    xMBUtilSetBits(dataBuf,16,0,0x1);

结果:dataBuf[4] = {0x00,0xfd,0x01,0x00};

setBits:xMBUtilSetBits(UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits,UCHARucValue)

ucByteBuf 内存排列:XXXXXXXXXXXXXXXX XXXXXXXX XXXXXXXX

        usBitOffset:0-78-15 16-23 24-32

       ucNBits:1-8

       ucValue:新值

getBits:xMBUtilGetBits(UCHAR* ucByteBuf, USHORT usBitOffset, UCHAR ucNBits)

ucByteBuf 内存排列:XXXXXXXXXXXXXXXX XXXXXXXX XXXXXXXX

          usBitOffset:0-7 8-15 16-23 24-32

          ucNBits:1-8

resData = xMBUtilGetBits(dataBuf,8,8); resData为0xfd





0 0
原创粉丝点击