一个字节中1个数的奇偶校验:
计数字节中前7位1的个数,字节的第八位做1个数的奇偶位(1个数为奇数,第8位置1;1个数为偶数,第8位置0)
注意:带奇偶校验位的字节范围变成了0~127;下面程序为无符号数据,若是带符号的数据要注意左移、右移数据的变化
- 将一个字节封装成带奇偶校验位的字节数
/******************************************************************************************
*@brief: 单字节的奇偶校验合成
*@param: 要合成校验位的字节数(无符号字节)
*@return: 返回带校验位的字节
*@descriptions: 单字节校验范围 0 ~ 127
* 字节前7位‘1’的个数为偶数,第8位置0:(0000 0000)0x00;
* 字节前7位‘1’的个数为奇数,第8位置1:(1000 0000)0x80;
********************************************************************************************/
uint8 ByteOddEvenCom(uint8 byte)
{
uint8 i;
uint8 n; /*计数1的个数*/
uint8 r; /*存结果*/
n =0;
for(i=0;i<7;i++)
{
if(((byte >>i)&0x01) == 0x01)
{
n++;/*计算一个字节前7位‘1’的个数*/
}
}
if((n&0x01) == 0x01)
{
r = byte | 0x80; /*'1'的个数为奇数,第8位置1*/
}
else
{
r = byte | 0x00; /*'1'的个数为偶数,第8位置0*/
}
return r;
}
- 将一个带奇偶校验位的字节数解析成无校验位的字节数
#define BYTE_CHECK_OK 0x01
#define BYTE_CHECK_ERR 0x00
/******************************************************************************************
*@brief: 单字节的奇偶校验
*@param: 需要校验的字节 (无符号字节)
*@return: 返回奇偶校验结果
*@descriptions: 单字节校验范围 0 ~ 127
* 偶数:(0000 0000)0x00;奇数:(1000 0000)0x80;
********************************************************************************************/
uint8 ByteOddEvenCheck(uint8 byte)
{
uint8 i;
uint8 n; /*计数1的个数*/
uint8 r; /*存结果*/
n =0;
for(i=0;i<7;i++)/*计数一个字节的前7位*/
{
if(((byte >>i)&0x01) == 0x01)
{
n++; /*计算一个字节前7位‘1’的个数*/
}
}
if((byte>>7) == (n&0x01))/*字节的第8位奇偶位与上面计数的奇偶数校验*/
{
r = BYTE_CHECK_OK; /*奇偶校验正确*/
}
else
{
r = BYTE_CHECK_ERR; /*奇偶校验错误*/
}
return r;
}
/*校验后需要把字节第8位清零*/
id_base = AT24CXX_ReadOneByte(ID_SUMTOTAL_ADDR);
read_base_ack = ByteOddEvenCheck(id_base);
if(read_base_ack == BYTE_CHECK_OK) /*读基区ID总数校验正确*/
{
IDSum = id_base & 0x7F; /*将第8位清零*/
}