【STM32】基带HDB3编解码系统设计


一、设计背景及说明

  长期以来,人类进行信息交互的基本方式不外乎语言、文字和图像。随着数字技术的发展,三大信息网:电话、电视、和因特网在数字通信的平台上融为一体的趋势日益加速。一方面是通信技术一日千里的发展,技术更新的周期越来越短;另一方面是人们对信息数量和质量的需求不断增长,如何更加有效、更加可靠、更加安全的传输信息,成为人们非常关注的问题。
  数字通信具有许多优良的特性,数字处理的灵活性使得数字传输系统中传输的数字信息既可以来自计算机,电传机等数据终端的各种数字代码,也可以是来自模拟信号经过数字化处理后的脉冲编码PCM信号等。在原理上,数字信息可以直接用数字代码序列表示和传输,但是在实际的传输中,视系统的要求和信道的情况,一般需要进行不同形式的编码,并且选用一组取值有限的离散波形表示这些取值离散的波形可以是数字带通信号,也可以是数字基带信号。数字基带信号的传输是数字通信系统的重要组成部分之一。
  在数字通信中,一般由信源发出的数字基带信号含有丰富的低频分量,甚至直流分量,这些信号往往不宜直接用于传输,易产生码间干扰进而直接影响传输的可靠性,为了使基带信号能适合在基带HDB3编码的设计信道中传输,通常需要经过基带信号变换。而为了用更短的代码表达同样多的信息,人们提出了压缩代码长度地方法,并发明了多种压缩方法和实施方案,统称为信源编码。为了及时发现并纠正信息传输中出现的错误,人们采用了各种检错和纠错技术,由此发展起来了信道编码技术,它使通信更加可靠。在编码过程中,不同码型有不同的特点和不同的用途。例如AMI码的传号交替反转,这种码型无直流成分和很小的低频成分,利于在一般的基带信道中传输,但它可能出现四连0现象,不利于接收端的定时信号提取。
  为了保持AMI码的优点而克服其缺点提出了HDB3码三阶高密度双极性码。HDB3码具有编码规则简单,无直流,低频成份少,可打破长连“0”和对定时信号的恢复十分有利等优点。综合上述情况,本文提出了基于C语言的HDB3编码的设计方案。设计方面包括规划基于C语言的HDB3编码设计的总体方案,合理利用各种软硬件资源;基于C语言的HDB3编码的软件实现。


二、设计目标与任务

2.1 设计目标

  信号在信道的传输过程中,如何才能保证信号失真最小且编码与译码的准确性是本次电子设计研究的目标。一个完整的通讯系统,当信号经过一定距离的传送后,总会受到干扰、移相和衰减,因而需要对数字信号进行再生。从信源输出的信号一般是0 1两种状态的单极性NRZ码,在进行数字信号传输时,考虑到传输信道的特点,将信息比特变换为适合于在信道中传输的数字信号,即进行线路编码。
  传统的基带信号含有丰富的直流和低频分量,这些信号不适宜在信道中传输。为了使得终端机编码输出的由0和1组成的单极性数码流适应于传输信道的特性,还必须经过码型变换,即对信号进行编码。选择编码码型时一般应考虑几方面的因素,比如从线路码流中容易提取时钟,码型中不宜含有直流分量,高、低频成分应尽量减少,设备应简单,易于实现码型变换和码型反变换的调试等。

2.2 设计任务

 (1)CPU采用FPGA或STM32或其它。
 (2)在观测点2能够看到AD采样之后的原始数据流,可以用CPU IO口进行输出。
 (3)在观测点3与观测点2进行对比,验证编码的正确性。
 (4)完成相关数据的本地显示。


三、设计原理

3.1 HDB3 码的介绍

   HDB3码即三阶高密度双极性码(High Density Bipolar of Order3,简称:HDB3码)是一种适用于基带传输的编码方式,“三阶” 通俗讲就是最多3个连0码元,“ 高密度双极性”就是没有直流分量,不会连续出现+1或-1,它是为了克服AMI码的缺点而出现的,具有能量分散,抗破坏性强等特点。
   三阶高密度双极性码用于所有层次的欧洲E-carrier系统,HDB3码将4个连续的"0"位元取代成"000V"或"B0OV"。这个做法可以确保连续的相隔单数的一般B记号。

3.2 HDB3 的编码转换规则

HDB3码的编码规则主要分为3步:
 1.先将消息代码变换成AMI码,若AMI码中连0的个数小于4,此时的AMI码就是HDB3码;
 2.若AMI码中连0的个数大于等于4,则将每4个连0小段的第4个0变换成与前一个非0符号(+1或-1)同极性的符号,用表示(+V,-V);
 3.为了不破坏极性交替反转,当相邻V符号之间有偶数个非0符号时,再将该小段的连0码元段的第1个0变换成+B或-B,B的符号与前一非零符号的相反,并让后面的非零符号从符号开始再交替变化。
 例如:
   消息代码: 10000100001 100001 1
   AMI码: +10000-10000+1-10000+1-1
   HDB3码:+1 000+V-1000-V+1-1 +B00+V-1 +1
   HDB3码: +1000+1-1000-1 +1-1 +100+1-1 +1

3.3 HDB3 码的解码转换规则

   虽然编码很复杂,但解码规则很简单,就是把原来的取代节(4个连零)找到即可,若3连"0"前后非零脉冲同极性,则将最后一个非零元素译为零,如+1000+1就应该译成10000", 否则不用改动;若2连"0"前后非零脉冲极性相同,则两零前后都译为零,如-100-1, 就应该译为0000,否则也不用改动。再将所有的-1变换成+1后,就可以得到原消息代码。
 例如:
   HDB3: 0+1 00-1000-1 +1000+1-1 +1-1 00-1 +1 00-1
   译码: 01 001 00001000011000000100 1


四、设计过程

4.1 HDB3码的系统结构与方案设计

图 4-1 发送端系统结构图  

图 4-2 接收端系统结构图

4.2 HDB3码硬件电路设计与搭建

   在硬件电路中,我们使用了STM32作为CPU,实验室信号发生器作为信号源(使用模拟电压信号),使用STM32上的LED屏作为显示模块,形成一个简单的硬件电路完成HDB3码的编码与解码。

4.3 HDB3码的软件设计过程
4.3.1 HDB3码编码译码功能设计

   HDB3编码主要分为3个部分消息码转换为AMI码,由于AMI码存在一定缺点,再进行HDB3编码,HDB3码编码判断当出现4个连0时,第4个0变为V,加V后根据规则判断第1个0是否需要变为B(V和B本质上均为1)。
   AMI码部分:对定义长度数组进行循环判断,当源码为0时,AMI码一定为0,当源码为1时,进行判断,第奇数个1 时AMI码为+1,第偶数个1 时AMI码为+1,此时完成源码到AMI码转换。
   HDB3码编码部分:对定义长度数组进行循环判断,当源码为0时,判断连0个数是否大于4,当连0个数大于4时,此时第4位为V码,根据初始定义V码极性为正,对后续V码进行正负交替变换,并更新最后一个V码状态,确定V码正负状态后,需要对每一个V码及它对应的前一个信码的符号进行判断,若极性不同,则需要增加同极性补码B。如果第一位源码为1,则对应HDB3码的信码极性为+1,此后正负交替即可,将编码结果保存在相应数组中。
   HDB3码译码部分:对HDB3码进行译码,对定义长度数组进行循环判断,当HDB3码为0时,译码结果一定为0,当HDB3码为1或-1时,如果当前HDB3码极性与前一个信码极性相同且连续0的个数大于等于2个,则当前HDB3码是V码,译码结果为0;如果连续0的个数等于2个,则前一个信码是补信码,译码结果为0;如果当前HDB3码是信码(含B及B’),则译码结果是1,完成HDB3译码,将译码结果保存在相应数组中。

4.3.2 AD转换模块

   在AD转换模块中,将模拟信号经ADC通道1读入,存入buff数组中,经过精度转换计算出电压值(有效值),由于STM32自身运算速率及LCD屏扫描频率的限制,我们对输入的瞬时信号的最大幅度进行检测,仅取最大幅度的有效值为最终电压值,由于LCD显示函数对小数点的显示的不支持,为简化操作,我们将有效值电压以mV为单位(X1000倍)显示在波形区域的左侧。同时我们在LCD屏上以0.3V/格的单位精度画出buff数组中存储的输入信号的波形图(幅值为有效值)。


五、结论

5.1 调试的过程与结果展示

图 5-1 方波在STM32上正常显示


图 5-2 正弦波在STM32上正常显示

图 5-3 两路信号相减得到HDB3码

   验证一:通过上图可以观察到,通过红绿两路信号进行作差,得到紫色波形,即HDB3编码波形,结果验证正确。

图 5-4 两路信号相减得到HDB3码

   验证二:通过上图可以观察到,通过红绿两路信号进行作差,得到紫色波形,即HDB3编码波形,结果验证正确。

图 5-5 两路信号相减得到HDB3码

   验证三:通过上图可以观察到,通过红绿两路信号进行作差,得到紫色波形,即HDB3编码波形,结果验证正确。


六、附录

(一)做的过程中编的一些函数
1、AMI码 HDB3码 .c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LENGTH 500  // sequence lengthvoid AMI_Encoding(char *AMI, const char *source, int len);
void HDB3_Encoding(char *hdb3, const char *source, int len);
void HDB3_Decoding(char *source, const char *hdb3, int len);
/*
主函数,程序开始*/
int main()
{unsigned int i = 0;FILE *file = NULL;char SOURCE[LENGTH];char AMI[LENGTH];char HDB3[LENGTH];char SOURCE1[LENGTH];file = fopen("test_out.txt","w");if(file == NULL){printf("Error!");exit(1);}srand((unsigned)time(NULL));//设置随机数种子fprintf(file,"source:  ");for(i = 0; i < LENGTH ; i++){//生成随机0、1序列,写入文件*(SOURCE+i) = (rand())&0x01;fprintf(file," %d ",*(SOURCE+i));}AMI_Encoding(AMI,SOURCE,LENGTH);fprintf(file,"\r\nAMI:     ");for(i = 0; i < LENGTH ; i++){//AMI码写入文件if(*(AMI+i) >= 0)fprintf(file," %d ",*(AMI+i));elsefprintf(file,"%d ",*(AMI+i));}HDB3_Encoding(HDB3,SOURCE,LENGTH);fprintf(file,"\r\nHDB3:    ");for(i = 0; i < LENGTH ; i++){//HDB3码写入文件if(*(HDB3+i) >= 0)fprintf(file," %d ",*(HDB3+i));elsefprintf(file,"%d ",*(HDB3+i));}    HDB3_Decoding(SOURCE1,HDB3,LENGTH);fprintf(file,"\r\ndecoding:");for(i = 0; i < LENGTH ; i++){//HDB3译码结果写入文件fprintf(file," %d ",*(SOURCE1+i));}fclose(file);for(i = 0; i < LENGTH ; i++)//check{//比较HDB3译码结果与源码是否相同if(*(SOURCE1+i) != *(SOURCE+i)){printf("decode error %d",i+1);break;}}  return 0;
}
/*
Encode the source code as AMI code.*/
void AMI_Encoding(char *AMI, const char *source, int len)
{unsigned int i = 0;unsigned int cnt_1 = 0;for(i = 0; i< len; i++){if(!source[i])//0{//源码是0的位置,AIM码一定是0*(AMI+i) = 0;}else//1{//源码第奇数个1转换为AMI码的1,第偶数个1转换为AMI码的-1cnt_1++;*(AMI+i) = (cnt_1&0x01)?1:-1;}}
}
/*
Encode the source code as HDB3 code.*/
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保证第一个信码极性为+1char last_v = -1;       //记录上一个V码极性,初始化为-1保证第一个V码极性为+1for(i = 0; i < len; i++){if(!source[i]){//源码为0cnt_0++;if(cnt_0 >= 4){//连续0的个数大于4cnt_0 = 0;*(hdb3+i) = (last_v&0x80)?1:-1;//保证V码极性交替变化last_v = *(hdb3+i);//更新last_vif((last_v != last_b)){//如果当前V码与前一个信码极性不同,则增加同极性的补信码*(hdb3+i-3) = last_v;last_b = last_v;//更新last_b}}else{*(hdb3+i) = 0;}}else{//源码为1cnt_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}}}
}
/*
Decode HDB3 code.*/
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,译码结果一定是0cnt_0++;*(source+i) = 0;}else{//HDB3码为1或-1if((*(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;}}
}
2、HDB3编译源程序(写入数组中).c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LENGTH 12  // sequence lengthvoid AMI_Encoding(char *AMI, const char *source, int len);
void HDB3_Encoding(char *hdb3, const char *source, int len);
void HDB3_Decoding(char *source, const char *hdb3, int len);
/*
主函数,程序开始*/
int main()
{unsigned int i = 0;char SOURCE[LENGTH];//源码char AMI[LENGTH];//编码生成AMI码char HDB3[LENGTH];//编码生成HDB3码char SOURCE1[LENGTH];//对HDB3码进行译码srand((unsigned)time(NULL));//设置随机数种子printf("源码:    ");for(i = 0; i < LENGTH ; i++){//生成随机0、1序列,写入数组SOURCE*(SOURCE+i) = (rand())&0x01;printf(" %d ",*(SOURCE+i));}printf("\n");printf("AMI码:   ");AMI_Encoding(AMI,SOURCE,LENGTH);for(i = 0; i < LENGTH ; i++){//AMI码写入数组AMIif(*(AMI+i) >= 0)printf(" %d ",*(AMI+i));elseprintf("%d ",*(AMI+i));}printf("\n");printf("HDB3码:  ");HDB3_Encoding(HDB3,SOURCE,LENGTH);for(i = 0; i < LENGTH ; i++){//HDB3码写入数组HDB3if(*(HDB3+i) >= 0)printf(" %d ",*(HDB3+i));elseprintf("%d ",*(HDB3+i));}printf("\n");printf("译码结果:");HDB3_Decoding(SOURCE1,HDB3,LENGTH);for(i = 0; i < LENGTH ; i++){//HDB3译码结果写入数组SOURCE1printf(" %d ",*(SOURCE1+i));}printf("\n");for(i = 0; i < LENGTH ; i++)//check{//比较HDB3译码结果与源码是否相同if(*(SOURCE1+i) != *(SOURCE+i)){printf("decode error %d",i+1);break;}}  return 0;
}
/*
@Encode the source code as AMI code.*/
void AMI_Encoding(char *AMI, const char *source, int len)
{unsigned int i = 0;unsigned int cnt_1 = 0;for(i = 0; i< len; i++){if(!source[i])//0{//源码是0的位置,AIM码一定是0*(AMI+i) = 0;}else//1{//源码第奇数个1转换为AMI码的1,第偶数个1转换为AMI码的-1cnt_1++;*(AMI+i) = (cnt_1&0x01)?1:-1;}}
}
/*
Encode the source code as HDB3 code.*/
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保证第一个信码极性为+1char last_v = -1;       //记录上一个V码极性,初始化为-1保证第一个V码极性为+1for(i = 0; i < len; i++){if(!source[i]){//源码为0cnt_0++;if(cnt_0 >= 4){//连续0的个数大于4cnt_0 = 0;*(hdb3+i) = (last_v&0x80)?1:-1;//保证V码极性交替变化last_v = *(hdb3+i);//更新last_vif((last_v != last_b)){//如果当前V码与前一个信码极性不同,则增加同极性的补信码*(hdb3+i-3) = last_v;last_b = last_v;//更新last_b}}else{*(hdb3+i) = 0;}}else{//源码为1cnt_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}}}
}
/*
description: Decode HDB3 code.*/
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,译码结果一定是0cnt_0++;*(source+i) = 0;}else{//HDB3码为1或-1if((*(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;}}
}
2.2、HDB3编译源程序(写入数组中)(-号代替-1).c

在功能模块的设计过程中,会交替产生+1、-1信号,如果直接通过代码实现-1信号,则无法得到-1波形,在STM32的LCD屏幕显示上也会出现一些问题。在代码设计阶段,可以导出两路0、1信号,再通过作差,便在波形显示上解决了无法显示-1这一问题。而直接显示出经过HDB3编码后的数组是比较容易实现的。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include<string.h>
#define LENGTH 12  // sequence lengthvoid AMI_Encoding(char *AMI, const char *source, int len);
void HDB3_Encoding(char *hdb3, const char *source, int len);
void HDB3_Decoding(char *source, const char *hdb3, int len);
/*
主函数,程序开始*/
int main()
{unsigned int i = 0;char SOURCE[LENGTH];//源码char AMI[LENGTH+1];//编码生成AMI码char HDB3[LENGTH];//编码生成HDB3码char SOURCE1[LENGTH];//对HDB3码进行译码char a=48;//printf("%x\n",a);srand((unsigned)time(NULL));//设置随机数种子printf("源码:    ");for(i = 0; i < LENGTH ; i++){//生成随机0、1序列,写入数组SOURCE*(SOURCE+i) = (rand())&0x01;printf(" %d ",*(SOURCE+i));}printf("\n");printf("AMI码:   ");memset(AMI,0,sizeof(AMI));AMI_Encoding(AMI,SOURCE,LENGTH);for(i = 0; i < LENGTH ; i++){//AMI码写入数组AMIif(*(AMI+i) == '-')printf(" %c ",*(AMI+i));elseprintf(" %c ",*(AMI+i));}//printf(" %s ",AMI);printf("\n");printf("HDB3码:  ");memset(HDB3,0,sizeof(HDB3));HDB3_Encoding(HDB3,SOURCE,LENGTH);for(i = 0; i < LENGTH ; i++){//HDB3码写入数组HDB3if(*(HDB3+i) == '-')printf(" %c ",*(HDB3+i));elseprintf(" %c ",*(HDB3+i));}//printf(" %s ",HDB3);printf("\n");printf("译码结果:");HDB3_Decoding(SOURCE1,HDB3,LENGTH);for(i = 0; i < LENGTH ; i++){//HDB3译码结果写入数组SOURCE1printf(" %c ",*(SOURCE1+i));}printf("\n");/*for(i = 0; i < LENGTH ; i++)//check{//比较HDB3译码结果与源码是否相同if(*(SOURCE1+i) != *(SOURCE+i)){printf("decode error %d",i+1);break;}}*/  return 0;
}
/*
@Encode the source code as AMI code.*/
void AMI_Encoding(char *AMI, const char *source, int len)
{int i = 0;unsigned int cnt_1 = 0;for(i = 0; i< len; i++){if(!source[i])//0{//源码是0的位置,AIM码一定是0*(AMI+i) = '0';}else//1{//源码第奇数个1转换为AMI码的1,第偶数个1转换为AMI码的-1cnt_1++;*(AMI+i) = (cnt_1&0x01)?'1':'-';}}
}
/*
Encode the source code as HDB3 code.*/
void HDB3_Encoding(char *hdb3, const char *source, int len)
{   int i = 0;unsigned int cnt_0 = 0; //记录连续0的个数char last_b = '0';        //记录上一个信码(含B及B')极性,初始化为0保证第一个信码极性为+1char last_v = '-';       //记录上一个V码极性,初始化为-1保证第一个V码极性为+1for(i = 0; i < len; i++){if(!source[i]){//源码为0cnt_0++;if(cnt_0 >= 4){//连续0的个数大于4cnt_0 = 0;// *(hdb3+i) = (last_v&0x80)?'1':'-';//保证V码极性交替变化if(last_v=='-'){*(hdb3+i)='1';}else{*(hdb3+i)='-';}last_v = *(hdb3+i);//更新last_vif((last_v != last_b)){//如果当前V码与前一个信码极性不同,则增加同极性的补信码*(hdb3+i-3) = last_v;last_b = last_v;//更新last_b}}else{*(hdb3+i) = '0';}}else{//源码为1cnt_0 = 0;if(last_b=='0'){//如果是第一个为1的源码,则对应HDB3码的信码极性为+1*(hdb3+i) = '1';last_b = '1';}else{if(last_b=='-'){*(hdb3+i)='1';}else{*(hdb3+i)='-';}//*(hdb3+i) = (last_b&0x80)?'1':'-';//保证信码极性交替变化last_b = *(hdb3+i);//更新last_b}}}}
/*
description: Decode HDB3 code.*/
void HDB3_Decoding(char *source, const char *hdb3, int len)
{int i = 0;unsigned int cnt_0 = 0; //记录连续0的个数char polarity = '0';      //记录前一个信码(含B及B')极性for(i = 0; i < len; i++){if(*(hdb3+i)=='0'){//HDB3码为0,译码结果一定是0cnt_0++;*(source+i) = '0';}else{//HDB3码为1或-1if((*(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;}}
}
3、int型数组转化为char型字符串型
// 子函数--int型数组转化为char型字符串型
int num_String(int x, char *s) // int x:数字数组;char *s:数字字符串数组
{int v, xx, i, j, n = 0;char c;xx = abs(x); // 求数值x的绝对值while (1){v = xx % 10;    // 对获取绝对值x的数值xx 求余数s[n] = v + '0'; // 数值转换为字符-存入到数组中n++;            // 位移以此存储多个余数存储xx = (xx - v) / 10; // 求整if (xx == 0)break;}if (x < 0) // 如果int型中数值为负数{s[n] = '-'; // 将负号标识赋给char型字符串数组s[]n++;        // 位移赋值}for (i = 0; i < n / 2; i++){c = s[i];            //赋值给char cs[i] = s[n - i - 1]; // 一共n个字符s[n - i - 1] = c;}s[n] = '\0'; // 字符串结束标识符
}
(二)工程中部分代码注释
1、HDB3编码函数部分

图 6.2.1 HDB3编码函数_变量申明
图 6.2.2 HDB3编码函数_对0的判断逻辑
图 6.2.3 HDB3编码函数_对1的判断逻辑

图 6.2.4hdb3码转两路信号存储输出

2、LCD显示函数部分

图 6.2.5 LCD_画网格

图 6.2.6 LCD_更新列(扫描画图部分)

图 6.2.7 LCD_显示三个波形

图 6.2.8 动态画波形

3、一些辅助函数

图 6.2.9 函数_十进制转二进制数组存储

图 6.2.10 函数_数组内整型转字符型


七、说明

相关的工程的文件,会上传到我的资源里。

功能:
1、对输入电压有效值进行HDB3编码,并绘出输入波形图。
2、12位HDB3编码显示。
3、波形图左侧显示输入电压有效值。
4、网格上格子的电压分度值为0.3V。(印象中)
5、网格左侧显示输入电压单位为mV。
6、一些引脚接线什么的,各位看代码吧,不记得了…

一些缺陷:
【以前做的,只记得一些印象比较深刻的点了】
1、采样率会影响LCD屏刷新波形的效果。(显示波形的重叠)
2、LCD波形刷新的间隔中,采样点后的数据直接丢弃了,这样做其实是不合理的。(后续验收了,也就没再修改优化)
3、LCD显示屏刷新率的限制确实很让人难受,确实没有用示波器显示FPGA输出的HDB3编码来的舒服。(FPGA的速度还是香的)
4、想用STM32来做出好的示波器的效果本身就有点不合理,做的这个只是个“伪示波器”。(别喷我/doge)
5、可能还有其他的一些点,但我忘了hhhhhh。

【最近在清理文件,可能会挑一部分做过的东西上传博客。】
看到这里了,点个赞再走吧!


【STM32】基带HDB3编解码系统设计(附完整代码)相关推荐

  1. 【手撕代码】HDB3编解码

    [手撕代码]HDB3编解码 1. 来源和需求 HDB3编解码任务来源于2023年3月4日"FPGA技术讨论群"的一次活动<101群第一次FPGA编码交流研讨会>,要求设 ...

  2. 智能窗帘传感器c语言程序,基于单片机的智能窗帘控制系统设计(附程序代码)

    基于单片机的智能窗帘控制系统设计(附程序代码)(论文18000字,程序代码) 摘要:二十一世纪初以来,科学技术不断发展,智能家居涌现于各家各户,人们越来越重视生活质量的提高.但是传统的手动开合窗帘耗时 ...

  3. 基于智能家居c语言程序代码,基于单片机的智能家居系统设计(附程序代码)

    基于单片机的智能家居系统设计(附程序代码)(任务书,开题报告,外文翻译,论文10000字) 摘要 基于近年来通信电子技术的高速发展,使得一些原来可望不可及的事关民生的技术变为可能,条件允许的情况下,人 ...

  4. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一)

    Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一) 本文目录: 一.[旋转的精灵女孩]案例运行效果 二.Three.js简介 三.Three.js代码正常运行显示条件 (1)不载入 ...

  5. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(二)

    Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(二) 本篇目录: 五.实例中所使用的代码语法详细解释 (1).构建一个三维空间场景 (2).选择一个透视投影相机作为观察点 (a).创 ...

  6. c++ 三次多项式拟合_线性回归进阶版,多项式线性回归讲解与实现(附完整代码)...

    每天给小编五分钟,小编用自己的代码,带你轻松学习深度学习!本文将会带你做完一个深度学习进阶版的线性回归---多项式线性回归,带你进一步掌握线性回归这一深度学习经典模型,然后在此基础上,小编将在下篇文章 ...

  7. 想要快速爬取整站图片?速进(附完整代码)

      大家好,我是不温卜火,是一名计算机学院大数据专业大三的学生,昵称来源于成语-不温不火,本意是希望自己性情温和.作为一名互联网行业的小白,博主写博客一方面是为了记录自己的学习过程,另一方面是总结自己 ...

  8. 吴恩达机器学习python实现(6):SVM支持向量机(文末附完整代码)

    所有的数据来源:链接:https://pan.baidu.com/s/1vTaw1n77xPPfKk23KEKARA 提取码:5gl2 1 Support Vector Machines 1.1 Pr ...

  9. PCL提取3D点云模型特征(3.0 FPFH快速点特征直方图)附完整代码

    一.概述 上一篇博客解释了PFH是什么以及如何利用PFH来提取点云的特征,那么讲了PFH(PCL提取3D点云模型特征(2.0 PFH点特征直方图 )附完整代码)之后肯定是要接着说FPFH的.本来想着把 ...

  10. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(三)

    Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(三) 本篇目录: 六.完整构建整个[旋转的精灵女孩]实例 (1).新建.启动webGL工程空间 (2).构建项目的目录层次结构 (2. ...

最新文章

  1. jenkins+maven+Tomcat+shell构建自动化部署
  2. 记一下常用shell,防止自己忘了。。。记性不好
  3. NSURLConnection 实现webView显示HTTPS页面
  4. plsql连接oracle数据库
  5. 图论--最短路--SPFA
  6. JavaScript算法相关
  7. mysql 角色管理_MySQL 8 用户和角色管理入门
  8. Python目录下中没有Script文件夹
  9. 项目改用GoModules管理依赖的方法和经验总结
  10. 随想录(程序员怎么用英文查资料)
  11. 免费素材下载:学校学院相关图标集
  12. C语言打印九九乘法表
  13. 宾馆管理c语言程序报告,C语言课程设计-宾馆客房管理系统报告.docx
  14. 如何修复VUM在客户端启用之后报数据库连接失败的问题
  15. Facebook受邀者的邮箱地址披露
  16. Java并发编程实战10:线程池
  17. 云烟阁--Java8系列之函数式接口和Lambda表达式(一)
  18. TextView中加横线
  19. mtd-utils交叉编译
  20. Wifi热点java_用笔记本电脑开启热点Java小程序

热门文章

  1. 简单方法去除图片水印图文教程
  2. python爬取微博用户信息_Python爬取新浪微博用户信息及内容
  3. 【论文阅读】Hierarchical Reinforcement Learning for Air-to-Air Combat 基于分层强化学习的空战决策
  4. 8位数控分频器的设计_基于FPGA的通用数控分频器的设计与实现
  5. 物联网概论(IoT)_Chp5 物联网通信 Zigbee/蓝牙/UWB/WLAN/WiMax
  6. matlab平稳性检验实例
  7. t检验的p值对照表_第十讲 R-两独立样本t检验
  8. ajax怎样上传多张图片,多图片Ajax上传
  9. 极域电子书包课堂管理系统怎么控屏_极域电子教室使用说明
  10. mysql数据库学习汇总