C语言实现HDB3编码与译码

HDB3

  AMI码存在出现长的连0串的缺点,为了克服AMI码的缺点,人们设计了HDB3码。HDB3码的编码规则如下:

  1. 把原二进制序列变成AMI码,检查AMI码的连0情况,当无3个以上连0码时,AMI码就是HDB3码。(我感觉实际应用时可以不要转AMI码这一步)
  2. 当出现4个或4个以上的连0码时,则将每4个连0小段的第4个0变成非0码,这个非0码用符号V表示。原来二进制序列中所有的1码称为信码,用符号B表示。B码与V码的正负必须满足两个条件:①B码和V码各自都应该保持极性交替变换(确保编好的码中没有直流成分);②V码必须与前一个B码同极性,如果不能满足这个条件,则将4个连0码的第1个0码变成与V码同极性的补信码,补信码用符号B’表示,同时要做出调整以保持B码与B’码保持极性交替变换。

  例如:

原二进制序列:0 1 0 0 0 0 1
   HDB 3码:0 1 0 0 0 1 -1
  特殊情况:
原二进制序列:0 0 0 0 0 0 0 0
   HDB 3码:1 0 0 1 -1 0 0 -1

C语言HDB3编码

/**
 * @description: Encode the source code as HDB3 code.
 * @param: hdb3   is a pointer to HDB3 code.
 *         source is a pointer to source code.
 *         len    is sequence length.
 * @return: none
 */
void HDB3_Encoding(char *hdb3, const char *source, int len)
{
    
       
    unsigned int i = 0;
    unsigned int cnt_0 = 0; //记录连续0的个数
    char last_b = 0;        //记录上一个信码(含B及B')极性,初始化为0保证第一个信码极性为+1
    char last_v = -1;       //记录上一个V码极性,初始化为-1保证第一个V码极性为+1
    for(i = 0; i < len; i++)
    {
    
    
        if(!source[i])
        {
    
    //源码为0
            cnt_0++;
            if(cnt_0 >= 4)
            {
    
    //连续0的个数大于4
                cnt_0 = 0;
                *(hdb3+i) = (last_v&0x80)?1:-1;//保证V码极性交替变化
                last_v = *(hdb3+i);//更新last_v
                if((last_v != last_b))
                {
    
    //如果当前V码与前一个信码极性不同,则增加同极性的补信码
                    *(hdb3+i-3) = last_v;
                    last_b = last_v;//更新last_b
                }
            }
            else
            {
    
    
                *(hdb3+i) = 0;
            }
        }
        else
        {
    
    //源码为1
            cnt_0 = 0;
            if(!last_b)
            {
    
    //如果是第一个为1的源码,则对应HDB3码的信码极性为+1
                *(hdb3+i) = 1;
                last_b = 1;
            }
            else
            {
    
    
                *(hdb3+i) = (last_b&0x80)?1:-1;//保证信码极性交替变化
                last_b = *(hdb3+i);//更新last_b
            }
        }
    }
}

C语言HDB3译码

/**
 * @description: Decode HDB3 code.
 * @param: hdb3   is a pointer to HDB3 code.
 *         source is a pointer to source code.
 *         len    is sequence length.
 * @return: none
 */
void HDB3_Decoding(char *source, const char *hdb3, int len)
{
    
    
    unsigned int i = 0;
    unsigned int cnt_0 = 0; //记录连续0的个数
    char polarity = 0;      //记录前一个信码(含B及B')极性
    for(i = 0; i < len; i++)
    {
    
    
        if(!(*(hdb3+i)))
        {
    
    //HDB3码为0,译码结果一定是0
            cnt_0++;
            *(source+i) = 0;
        }
        else
        {
    
    //HDB3码为1或-1
            if((*(hdb3+i) == polarity)&&(cnt_0 >= 2))
            {
    
    //如果当前HDB3码极性与前一个信码极性相同且连续0的个数大于等于2个
             //则当前HDB3码是V码,译码结果为0
                *(source+i) = 0;
                if(cnt_0 == 2)
                {
    
    //如果连续0的个数等于2个,则前一个信码是补信码,译码结果为0
                    *(source+i-3) = 0;//修改补信码处的译码结果
                }
            }
            else
            {
    
    //当前HDB3码是信码(含B及B'),译码结果是1
                *(source+i) = 1;
                polarity = *(hdb3+i);//记录信码极性
            }
            cnt_0 = 0;
        }
    }
}

  将HDB3码的编、译码函数编译成Matlab可以调用的.mexw64文件后,用Matlab绘制的波形图如下图所示,可见译码结果与原二进制序列相同。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/QDchenxr/article/details/106304820