赞
踩
对文章有任何问题可私信
一、题目分析
二、方案摘要
三、调制方式识别与解调
1、识别部分
2、解调电路部分
(1)AM、ASK
(2)FM、FSK
(3)PSK
四、参数估计部分
五、总结
本系统由STM32F103、前级处理电路、四路解调电路和屏幕构成,能够对AM、FM、2ASK、2FSK或2PSK进行解调并自动识别调制方式及参数测量。
题目如下:
对于基础部分来讲,与2022年部分省份省赛题目大体相同,但这次增加了数字调制方式的部分,尤其对于PSK的解调,做到完美是很不容易的;且本次大赛中组委会在答疑中对输出方式做了要求:输出波形是要真正解调出的,不能使用DDS等波形产生电路将分析后的调制波直接生成。比如我已经在单片机中分析出来了,调制波就是3KHz,直接使用DDS输出一个3KHz的正弦波或者方波,波形非常标准且系统简单。这样被禁止后就只能选择做出几路的解调电路,在识别后将信号分路处理。
在题目后面的说明中,对信号的各个参数都做了限制,我们在代码中可以根据这些限制,对数据进行一定程度的归一化,可以使数据更加精确。
本装置以STM32F103单片机为主控芯片。
首先通过本振源(这里我们使用的是AD9854)和乘法器AD835进行下变频至80kHz。使用单片机内置ADC采集信号,并在单片机内部完成信号类型的识别和相关参数的计算。
紧接着单片机根据识别结果,控制射频开关切换解调电路来解调相应信号;LCD屏幕显示出计算结果。
经过验证,本系统可正确分辨6种信号,并将调制信号解调,波形无明显失真;波形的相关参数的测量满足题目要求;显示屏等交互外设也运行正常。
对于CW、AM、FM、ASK、FSK、PSK六种信号,FM、FSK、PSK已经算是相对较为复杂的信号了,从时域区分十分困难,所以我们直接从频域进行分析。使用ST官方的FFT函数对ADC采样后的数据进行处理(这部分的文章特别多,也都比我讲的明白,我就不丢人了)。
我们根据题目基础部分与提高部分将系统区分为两个模式,分别为模拟调制模式与数字调制模式。
先来分析频谱,这里为了降低干扰和减少单片机运算量,利用上位机分析FFT后的数据,初步筛选频谱段,我这里选择300-512部分进行分析
- //模拟调制,分析频谱
- //寻找峰值,计算波峰个数
- int select_max_count(unsigned int *a)
- {
- int i,flag=0;
- int count=0,count2=0;
-
- for ( i=300; i < NPT/2; i++)
- {
- if ((a[i]>a[i+1]) && (a[i]>a[i-1]) && (a[i]> 40))
- {
- count++;
- }
- }
- if(count==1)
- {
- flag=1;
- return flag;
- }
-
- for ( i=220; i < NPT/2; i++)
- {
- if ((a[i]>a[i+1]) && (a[i]>a[i-1]) && (a[i]> 70))
- {
- count2++;
- }
- }
- if(count2 <= 3)
- {
- flag=2;
- return flag;
- }
- else
- {
- return count2;
- }
- }
- //波形判断
- void wave_judge(void)
- {
- int F2;
- float mf=4,ma,F1;
- float delta_f;
- u8 cnt;
- POINT_COLOR=BLACK; //画笔颜色黑色
- cnt= select_max_count(lBufMagArray);
- if(cnt == 1)
- {
- wave_mode = CW;
- Select_AM_CW(); //射频开关选择CW
- show_CW(); //显示CW参数
- }
- else if(cnt==2)
- {
- wave_mode = AM;
- Select_AM_CW(); //射频开关选择AM
- ma= calculate_ma(lBufMagArray)+0.1; //计算ma
- F1=AM_F(lBufMagArray);
- if(ma<=1&&ma>0.1)
- {
-
- show_AM(ma,F1);
-
- }
- }
- else
- {
- wave_mode = FM;
- Select_FM(); //射频开关选择FM
- F2 = FM_Found(lBufMagArray); //计算FM参数
- //found();
- mf = calculate_mf(); //计算mf
- if((mf<=3.75)&&(mf>=2.8))
- {
- mf=3;
- }
- if((mf>=3.8)&&(mf<=4.3))
- {
- mf=4;
- }
- if(mf>=5)
- {
- mf=5;
- }
- delta_f = mf * F2 *1000; //计算Δf
- show_FM(mf,delta_f); //显示FM参数
- LCD_ShowString(30,160,200,24,24,"F:");
- LCD_ShowFloat(100,160,24,F2,1,3);
- LCD_ShowString(180,160,200,24,24,"KHz");
- }
- }
-CW
在频谱中只有一个主峰
-AM
标准的AM波,在频谱中有一个主峰两个次峰
-FM
FM波在频域中也是相当复杂的,根据各个参数的不同,在频谱中的呈现也会不同,但遵循一定规律(后面参数计算会详细介绍),在主频两侧有多对边频,但峰的个数一定是大于3的,这里就可以根据频谱中锋的个数来进行识别。
第一步,当然也是分析频谱,这里再次强调,建议使用上位机分析一下数据,自己观察观察FFT处理后的数组数据,我这里就是实验了题目要求里的各个信号,分析每个信号的频谱特点,然后根据这些显著特点去识别;还有一个好处就是方便设定好阈值,到底是超过多少,才会被判定为峰,可以提高识别准确率。
比如在这里,FSK频谱中有多个峰,但ASK与PSK的频谱较为相似,将数据上传上位机后发现,ASK在低频部分有一峰,且对应横坐标就是调制信号的频率(也就是码速率的二分之一)。
- //数字调制部分
- //分析频谱属性
- int select_max_count2(unsigned int *a)
- {
- int i;
- int Max=0,count=0,flag=0;
-
-
-
-
- for(i=2;i < 30; i++)
- {
- if (a[i]>Max)
- {
- Max = a[i];
- }
- }
- if(Max>70)
- {
- flag=1;
- return flag;
- }
-
- for ( i = 80; i < 250; i++)
- {
- if ((a[i]>a[i+1])&&(a[i]>a[i-1])&&(a[i]>45))
- {
- count++;
-
- }
- }
-
- if(count>=2)
- {
- flag=2;
- return flag;
- }
- else
- {
- flag=3;
- return flag;
- }
-
- }
- void wave_judge2(void)
- {
- float speed = 6;
- float h,HH;
- u8 judge;
- POINT_COLOR=BLACK; //画笔颜色黑色
- judge = select_max_count2(lBufMagArray);
- if(judge == 1)
- {
- wave_mode = ASK;
- Select_ASK_FSK();
- speed = calculate_speed1(lBufMagArray);
- show_ASK(speed);
- }
- else if(judge == 2)
- {
- wave_mode = FSK;
- Select_ASK_FSK();
- show_FSK();
- speed=calculate_speed3(lBufMagArray);
-
- HH=calculate_HH(lBufMagArray);
- h=0.5+(HH/speed/1000);
- if(h>5)
- h=5.0;
- LCD_ShowFloat(130,100,24,speed,2,3);
- LCD_ShowString(200,100,200,24,24,"Kbps");
- LCD_ShowFloat(100,130,24,h,2,3);
- }
- else
- {
- wave_mode = PSK;
- Select_PSK();
- show_PSK();
- speed=calculate_speed1(lBufMagArray);
-
- LCD_ShowFloat(130,100,24,speed,2,3);
- LCD_ShowString(200,100,200,24,24,"Kbps");
-
- }
- }
-ASK
在低频部分有一个峰,可以直接筛选出来,识别为ASK。也可以在时域根据平坦度进行区分
-FSK
高频部分存在两个或以上个数的峰
-PSK
高频部分只存在一个峰
方案一:采用无源二极管检波
二极管检波只需要极少量无源器件即可完成解调,但是对小信号的解调,存在较为严重的失真。
电路最简单,不需要供电,需在前级进行放大处理
方案二:采用相干解调
使用乘法器电路,与本振信号相乘,经过滤波器输出解调信号。
电路简单,易于调试,但是是有源电路
方案三:采用FPGA数字解调
FPGA实现包络检波可以有效减少谐波失真,且在后级加滤波器即可完成检波。
综合以上三种方案,方案三过于复杂,方案一与方案二实际应用中效果差距微小,故选择方案一
方案一:采用模拟锁相环解调
使用NE564锁相环芯片,根据题目要求的信号围绕此芯片搭建电路。
题目要求的信号是窄带信号,在电路搭建上工作量较大
方案二:采用FPGA数字解调
使用FPGA对信号进行采样,使用相干解调调整参数完成解调,DAC输出。
综合以上两种方案,我们手边有现成的NE546电路模块,调节滑动变阻器,可以完成所需功能,所以使用方案一
方案一:采用模拟解调
使用鉴相器分析输入信号相位,单片机控制AD9910产生同频同相信号相乘,后进入比较器输出方波。
该方案系统较为复杂,容易受到干扰。
方案二:采用FPGA数字解调
将PSK信号放大后传入FPGA中,对PSK信号使用数字解调。
该方案易调试,且难度相对于方案一较低。
当时我们队对于FPGA的使用还不熟练,先采取的方案一。
方案一的重点就在相位的提取能否做到精准,最后在总测评就是因为这里提取的相位有偏差,导致解调出来的方波信号在顶部偶尔会产生漂移。有能力的话还是建议使用FPGA进行数字解调
-AM
通过频谱测量相关参数,主峰和次峰横坐标差即为调制信号频率,对于ma的计算,我这里用的是次峰与主峰的比值乘2,不过大赛结束之后我觉得最好是可以找到主峰左右两个峰相加直接除以主峰,可能算的更精准一点
- //计算AM参数
- float calculate_ma(unsigned int *a)
- {
- int i,j = 0;
- float aMax = 0.0,aSecondMax = 0.0,aSecondMax_pr = 0.0,aMax_pr = 0.0;
- float ma;
- int nMax = 0,nSecondMax=0;
-
- for ( i = 300; i < NPT/2; i++)//i必须是1,是0的话,会把直流分量加进去!!!!
- {
- if (a[i]>aMax)
- {
- aMax = a[i];
- nMax=i;
- }
- }
-
- for ( i = 300 ; i < NPT/2 ; i++)
- {
- if (nMax == i)
- {
- continue;
- }
- if ((a[i]>aSecondMax)&&(a[i]>a[i+1])&&(a[i]>a[i-1]))
- {
- aSecondMax = a[i];
- nSecondMax=i;
-
- }
- }
-
- ma = (aSecondMax* 2) / aMax;
- return ma;
- }
-
-FM
通过频谱测量相关参数,主频和第一变频差值(主频与第一个次峰间隔)即为调制信号频率F。计算调频系数,这里我们就要引出贝塞尔函数进行分析了 。
贝塞尔曲线如下
我们在数据中主频的值定为,第一边频就定为
,以此类推
之后,我们要计算出、
、
、
根据贝塞尔函数库中的值进行对应,算出。
为了精确计算值,也可以进行了最短欧氏距离的匹配。
ASK
上文提到过,ASK经过FFT处理后,在低频部分有一峰,此峰横坐标即为二进制码速率的一半。
FSK
在频谱中,FSK一般只有两个峰,峰的宽度就是二进制码速率,理论上两个峰的宽度相同,但实际中略有差异,这里可以做一个平均数处理;移频系数需要算出两个载频的频率差,再与二进制码速率进行一个比值即可。
PSK
通过频谱测量参数,频谱主峰的宽度就为二进制码速率。
这里也建议准备打电赛信号类题目的弟弟妹妹们,如果时间宽裕,尽量接触一下FPGA,就比如在这个题目中我们使用的这套方案只有在PSK解调波形上有些瑕疵,被扣了两分,止步国二,在总测评时候看了一些其他学校的队伍,FPGA在这部分的效果确实无话可说,也算是输的明明白白。
总体来说,我认为这道题的难点在FM参数的计算和PSK的解调,评分表的重点还是在识别与参数的精准度。只要把这里做好,解调相对来说就比较简单了。
竞赛结束也好久了,最近终于静下心来写这篇文章。本人各方面水平也一般,不知道有没有讲清楚,如果本篇文章有不足之处,也请大家多多包涵。后续我会把完整项目发出来,供大家做一个大致的参考。
2024年1月24日
队友在B站上传的演示视频 https://b23.tv/beM5XVr,展示的不全,可以参考
2024年3月25日
资源下架了,交流可以联系QQ:2790956880
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。