汉明码、FEC(7,4)实现--防迷路,通过博客收藏

例如输入的数据为(a3~a6) 0001 

    根据监督位计算结果的表单得到a0 a1 a2的值为011

计算得到数据0001011。

若对方收到的数据为0101011。

分解得到(a3~a6)0101,(a0~02)011。

根据监督位计算结果的表单得值与011不相等得知有错误。

S1=1 S2=1 S3=0, 得到错误码是A5,所以正确的数据应该为000111

 

若对方收到的数据为1101011。

分解得到(a3~a6)1101,(a0~02)011。

根据监督位计算结果的表单得值与011不相等得知有错误。

S1=0 S2=0 S3=1, 得到错误码是A1,所以正确的数据应该为1101010,解包错误

 

若对方收到的数据为1101010。

分解得到(a3~a6)1101,(a0~02)010。

根据监督位计算结果的表单得值与011不相等得无错误。

 

说明:    

S1 S2 S3用来计算错误码的位置。

a1 a2 a3用来校验是否错误。

 

数据组成  a6 a5 a4 a3 a2 a1 a0 构成一个数据段,

 

相关公式

  a2 = a6⊕a5⊕a4 

  a1 = a6⊕a5⊕a3 

  a0 = a6⊕a4⊕a3

      S1 = a6⊕a5⊕a4⊕a2 (1)式 

  S2 = a6⊕a5⊕a3⊕a1 (2)式 

  S3 = a6⊕a4⊕a3⊕a0 (3)式 

 

相关表单

  S1 S2 S3 错码的位置 

  0  0  1   a0 

  0  1  0   a1 

  1  0  0   a2 

  0  1  1   a3 

  1  0  1   a4 

  1  1  0   a5 

  1  1  1   a6 

  0  0  0   无错 

监督位计算结果

码   字

码   字

信 息码元(输入数据)

监 督 元(A0~A2)

信 息码元(输入数据)

监 督 元(A0~A2)

0

0  0  0  0

0  0  0

8

1  0  0  0

1  1  1

1

 0  0  0  1

0  1  1

9

1  0  0  1

1  0  0

2

 0  0  1  0

1  0  1

10

1  0  1  0

0  1  0

3

0  0  1  1

1  1  0

11

1  0  1  1

0  0  1

4

0  1  0  0

1  1  0

12

 1  1  0  0

0  0  1

5

0  1  0  1

1  0  1

13

 1  1  0  1

0  1  0

6

0  1  1  0

0  1  1

14

 1  1  1  0

1  0  0

7

0  1  1  1

0  0  0

15

 1  1  1  1

1  1  1

 

结论:

在速率慢或者简单误码的地方可以使用,若误码率高的地方反而会引起不良。并且只能纠正一个错误码。

 

#include "fec.h"

fec::fec()
{

}

void fec::Code(unsigned char *pIn, unsigned int InSLen, unsigned char *pOut, unsigned int *OutSLen){
    unsigned char CodeTable[16] = {0x0, 0x3, 0x5, 0x6,
                          0x06, 0x5, 0x3, 0x0,
                          0x7, 0x4, 0x2, 0x1,
                          0x1, 0x2, 0x4, 0x7};
    /* 进行比特位操作 */
    unsigned char H = 0;
    unsigned char L = 0;
    unsigned char OutCur = 7;
    unsigned int Ops = 0;
    pOut[Ops] = 0xAA;

    for(int i=0; i<InSLen; i++){
        H = (pIn[i]>>4)&0x0F;
        L = pIn[i]&0x0F;
        H = ((CodeTable[H]^0x04)&0x07) + (H<<3);
        L = ((CodeTable[L]^0x04)&0x07) + (L<<3);
        /* 进行位压缩 */
        for(int j=0; j<7; j++){
            if(H&(0x40>>j)){    /* 为1 */
                pOut[Ops] |= (0x01)<<OutCur;
            }else{
                pOut[Ops] &= ~((0x01)<<OutCur);
            }

            if(OutCur==0){
                OutCur = 7;
                Ops ++;
                pOut[Ops] = 0xAA;
            }else{
                OutCur --;
            }
        }
        for(int j=0; j<7; j++){
            if(L&(0x40>>j)){    /* 为1 */
                pOut[Ops] |= (0x01)<<OutCur;
            }else{
                pOut[Ops] &= ~((0x01)<<OutCur);
            }

            if(OutCur==0){
                OutCur = 7;
                Ops ++;
                pOut[Ops] = 0xAA;
            }else{
                OutCur --;
            }
        }
    }
    if(OutCur!=7){
        Ops ++;
    }
    *OutSLen = Ops;
}
void fec::Decode(unsigned char *pIn, unsigned int InSLen, unsigned char *pOut,unsigned  int *OutSLen){
    unsigned char CodeTable[16] = {0x0, 0x3, 0x5, 0x6,
                          0x06, 0x5, 0x3, 0x0,
                          0x7, 0x4, 0x2, 0x1,
                          0x1, 0x2, 0x4, 0x7};
    unsigned char ErrorTable[7] = {0,1,3,2,4,5,6};
    /* 进行比特位操作 */
    unsigned char HByte = 0;
    unsigned char LByte = 0;
    unsigned char HCode = 0;
    unsigned char LCode = 0;
    unsigned char OutCur = 0;
    unsigned int Ops = 0;
    unsigned int All = 0;
    unsigned char s1 = 0, s2 = 0, s3 = 0;
    unsigned char s = 0;
    unsigned char Wid = 0;

    InSLen = InSLen * 8 / 14;

    for (int i=0; i<InSLen; i++) {
            /* 解除高字节编码 */
        HByte = 0;
        LByte = 0;
        for(int j=0; j<7; j++){
            if(pIn[Ops]&(0x80>>OutCur)){
                HByte |=  ((0x40)>>j);
            }

            if(OutCur>=7){
                OutCur = 0;
                Ops ++;
            }else{
                OutCur ++;
            }
        }
        for(int j=0; j<7; j++){
            if(pIn[Ops]&(0x80>>OutCur)){
                LByte |=  (0x40)>>j;
            }

            if(OutCur>=7){
                OutCur = 0;
                Ops ++;
            }else{
                OutCur ++;
            }
        }

        HCode = (HByte^0x04) & 0x07;
        LCode = (LByte^0x04) & 0x07;
        HByte = (HByte >> 3)&0x0F;
        LByte = (LByte >> 3)&0x0F;
        if(CodeTable[HByte]!=HCode){
            /* 进行补偿 */
            s1 = (((HByte&0x08)>>3) + ((HByte&0x04)>>2) + ((HByte&0x02)>>1) + ((HCode&0x04)>>2))&0x01 ;
            s2 = (((HByte&0x08)>>3) + ((HByte&0x04)>>2) + (HByte&0x01) + ((HCode&0x02)>>1))&0x01 ;
            s3 = (((HByte&0x08)>>3) + ((HByte&0x02)>>1) + (HByte&0x01) + (HCode&0x01))&0x01 ;
            s = (s1<<2)+(s2<<1)+s3;
            if(s>0){
                Wid = ErrorTable[s-1];
                if(Wid>=3){
                    Wid -= 3;
                    if(HByte&(0x01<<Wid)){
                        HByte &= ~(0x01<<Wid);
                    }else{
                        HByte |= (0x01<<Wid);
                    }
                }
            }

        }
        if(CodeTable[LByte]!=LCode){
            /* 进行补偿 */
            s1 = (((LByte&0x08)>>3) + ((LByte&0x04)>>2) + ((LByte&0x02)>>1) + ((LCode&0x04)>>2))&0x01 ;
            s2 = (((LByte&0x08)>>3) + ((LByte&0x04)>>2) + (LByte&0x01) + ((LCode&0x02)>>1))&0x01 ;
            s3 = (((LByte&0x08)>>3) + ((LByte&0x02)>>1) + (LByte&0x01) + (LCode&0x01))&0x01 ;
            s = (s1<<2)+(s2<<1)+s3;

            if(s>0){
                Wid = ErrorTable[s-1];
                if(Wid>=3){
                    Wid -= 3;
                    if(LByte&(0x01<<Wid)){
                        LByte &= ~(0x01<<Wid);
                    }else{
                        LByte |= (0x01<<Wid);
                    }
                }
            }
        }

        pOut[All] = ((HByte<<4)+LByte)&0xFF;
        All ++;
    }
    *OutSLen = All;
}
 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值