📄 hm16.c
字号:
//16比特汉明码测试程序(原始数据11字节,编码结果为16字节)
// [16,11,4] 增广汉明码校验矩阵: |
// D15 D14 D13 D12 D11 D10 D9 D7 D6 D5 D3 D16 D8 D4 D2 D1 校验码
// | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | C4=0FFFFH
// | 1 1 1 1 1 1 1 0 0 0 0 0 1 0 0 0 | C3=0FE08H
// | 1 1 1 1 0 0 0 1 1 1 0 0 0 1 0 0 | C2=0F1C4H
// | 1 1 0 0 1 1 0 1 1 0 1 0 0 0 1 0 | C1=0CDA2H
// | 1 0 1 0 1 0 1 1 0 1 1 0 0 0 0 1 | C0=0AB61H
unsigned int err[16]={0x0000,0x0001,0x0002,0x0020,0x0004,0x0040,0x0080,0x0100,
0x0008,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};//错误图样
unsigned char S[11]={0x05,0x16,0x27,0x38,0x49,0x5A,0x6B,0x7C,0x8D,0x9E,0xAF};//原始数据
unsigned char D[16]; //原始数据的汉明码(发送的内容)
unsigned char R[11]; //解码结果(接收的内容)
unsigned char parity (unsigned int k ) //16比特偶校验
{
int i;
unsigned char t=0;
for (i=0;i<16;i++) {
if ( k & 0x0001 ) t ^= 0x01;
k >>= 1;
}
return t;
}
void TRANS ( ) //编码程序(模拟发送)
{
unsigned char c0,c1,c2,c3,c4;
int i,j;
unsigned int m;
c0=S[8];c1=S[9];c2=S[10];//后三字节用来拆分
for (i=0,j=0;i<8;i++) { //分8组进行编码
c3=S[i];c4=0; //从前8个字节中取一个字节,作为高字节
if ( c0 & 0x80 ) c4 += 0x80;//从后三字节中各取一比特,作为低字节的高3位
if ( c1 & 0x80 ) c4 += 0x40;
if ( c2 & 0x80 ) c4 += 0x20;
c0 <<= 1 ;c1 <<= 1 ;c2 <<= 1 ;//后三字节进行移位,丢弃已经使用的信息
m = 256*c3 + c4 ;//将两个字节拼装为16比特无符号整数
if ( parity ( m & 0xAB61 ) ) m += 1; //生成校验位D1
if ( parity ( m & 0xCDA2 ) ) m += 2; //生成校验位D2
if ( parity ( m & 0xF1C4 ) ) m += 4; //生成校验位D4
if ( parity ( m & 0xFE08 ) ) m += 8; //生成校验位D8
if ( parity ( m ) ) m += 16; //生成校验位D16
D[j++]=c3; D[j++]=m%256; //输出两字节编码结果
}
}
int RECEV ( ) //解码程序(模拟接收)
{
int i,j,l;
int k=1; //初始化解码成功标志
unsigned char c1,c2,p,q,r;
unsigned int m,n;
p=q=r=0;
for (i=0,j=0;i<8;i++,j++) { //分为8组处理
c1=D[2*i];c2=D[2*i+1]; //每组两个字节
m=256*c1+c2; //将两个字节拼装为16比特无符号整数
n=0; //校验结果初始化
if ( parity ( m & 0xAB61 ) ) n += 1; //计算校验结果D1
if ( parity ( m & 0xCDA2 ) ) n += 2; //计算校验结果D2
if ( parity ( m & 0xF1C4 ) ) n += 4; //计算校验结果D4
if ( parity ( m & 0xFE08 ) ) n += 8; //计算校验结果D8
l = parity ( m ) ; //计算校验结果D16
if ( n && !l) k=0; //两个差错,解码失败
m ^= err[n]; //纠错处理
R[j]=m/256; //输出高字节的8比特信息
p<<=1;q<<=1;r<<=1; //将3比特信息拼装保存
if ( m & 0x0080) p++;
if ( m & 0x0040) q++;
if ( m & 0x0020) r++;
}
R[8]=p;R[9]=q;R[10]=r; //输出拼装出来的3字节信息。
return k; //返回解码是否成功的信息
}
main ( )
{
int f; //解码成功标志
TRANS ( ) ; //对原始数据进行汉明编码(模拟发送)
f = RECEV ( ); //对没有干扰的数据进行解码(模拟接收),f=1,成功.
D[5] ^= 0x20 ; //在接收数据中制造一比特差错
f = RECEV ( ); //对有干扰的数据进行解码(模拟接收),f=1,成功.
D[8] ^= 0x24 ; //在接收数据中制造两比特差错
f = RECEV ( ); //对有干扰的数据进行解码(模拟接收),f=0,失败.
while (1) ; //在这一行设置断点,中止程序运行,以便观察程序运行的结果
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -