简介:2024年电赛C题「无线传输信号模拟系统」江苏省一等奖实现方案,适合备战电赛的电子信息、通信工程专业学生及需复现AM调幅与多径模拟链路的开发者。系统以STM32F407ZGT6为主控,驱动DDS产生四路频率、相位相对独立的信号,作为直达与多径两路AM波的载波与调制源;经DAC偏置、加法器与AD835乘法器完成调幅后由运放放大至目标幅值,多径支路再经PE4302程控衰减器调节增益,最终合路输出,全面阐明幅值与相移的独立控制思路。压缩包共2000个文件、约83.75MB,以1096个.c源文件和831个.h头文件为工程主体,辅以txt、md说明文档与少量Python脚本、json配置。已有2280人学习下载,适合对照复现硬件链路、梳理调幅逻辑,并借鉴省一等奖方案的指标分配与调试路径。
1. 无线传输信号模拟系统:先把指标拆成能测的量
无线传输信号模拟系统看着像一道纯射频题,真正拉开差距的却是测量与标定。评委不会只看你能不能发出波形,而是拿频谱仪、示波器逐项测频率误差、衰减步进误差和解调失真。所以这套方案的第一步不是选芯片,而是把题面指标拆成一张「能被仪器测出来」的清单,再反推发射、信道、接收三级架构。它适合正在做同类赛题、需要一份能直接当模板改的完整方案的人,也适合课程设计里要做调制解调链路的同学当素材用。下面按需求、架构、硬件、软件、避坑、验收六段展开,能对着抄的部分我都写到了寄存器和电阻值这一层。
2. 总体方案与选型:从信道模型反推三级架构
2.1 指标拆解与可测性设计
题目给的是功能描述,验收给的是数字,中间那层翻译工作得自己做。通常的做法是先把题面每一句话翻译成一个「量 + 仪器 + 测法」的三元组,翻译不出来的条款,多半是你在验收现场会被问住的地方。下表是按同类题目常见要求整理的一份拆解样例,具体数值以你手上的题面为准,但拆解的粒度可以直接搬。
| 指标项 | 目标值(样例) | 测量仪器 | 测法 |
|---|---|---|---|
| 载波频率范围 | 100 kHz~10 MHz | 频率计/频谱仪 | 单音输出,读峰值频率 |
| 频率步进 | 1 kHz | 频率计 | 逐点切换,记录实际值 |
| 输出幅度 | 10 mVpp~2 Vpp(50 Ω) | 示波器 | 高阻探头+终端匹配 |
| 衰减范围/步进 | 0~60 dB / 1 dB | 频谱仪 | 以 0 dB 为基准逐档读差 |
| 衰减误差 | ≤1 dB | 频谱仪 | 全量程 61 点扫一遍 |
| 调制方式 | AM/FM/ASK/FSK | 频谱仪+示波器 | 看边带与解调波形 |
| 调制深度 | 0~100% 连续可调 | 示波器 | 包络最大最小值算 |
| 解调失真 | ≤5% | 失真仪/FFT | 1 kHz 基带,算谐波比 |
| 频率测量误差 | ≤1% | 信号源比对 | 外接标准源交叉验证 |
这张表有两个作用。一是决定架构:61 个衰减点要逐点可测,意味着衰减网络必须程控且单调,靠手拧电位器一定过不了。二是决定调试顺序:先把单音通路打通并标定,再往上叠调制,否则调制一加,你根本分不清误差来自调制还是来自通路。我一般会把这张表打印出来贴在工位上,每打通一项打个勾,最后答辩的实测数据也从这张表里出。
2.2 三条实现路线的取舍
同一个功能,市面上常见的做法有三条,成本、调试量和最终指标差别很大,选错路线后期基本救不回来。
| 路线 | 频率分辨率 | 杂散/相噪 | 调试难度 | 器件成本 | 适合场景 |
|---|---|---|---|---|---|
| 分立 VCO + 变容管 | 低,受限于调谐电压噪声 | 相噪一般,温漂明显 | 中,需反复调谐 | 低 | 只要求粗调频、指标宽松 |
| DDS + 模拟信道 | 高,亚赫兹级 | 时钟馈通和杂散需滤波 | 中高,重在滤波与屏蔽 | 中 | 本题主流选择,指标好控 |
| 全数字(FPGA+高速 DAC/ADC) | 极高 | 取决于 DAC 与时钟质量 | 高,但可复现 | 高 | 需要多径、任意波形、误码统计 |
三条路线里,分立 VCO 的问题是频率靠电压定,温漂一小时能跑掉几百赫兹,衰减步进还得另配衰减器,越做越散。全数字路线灵活,多径、噪声、衰落全在数字域做,但高速 DAC 的模拟前端一样绕不开滤波器,成本还上去了。这套方案选的是中间那条:DDS 负责频率与相位精度,模拟链路负责衰减与检波,FPGA 只在需要多径和噪声叠加时介入数字域。理由是题目的核心指标是频率准确度和衰减精度,这两项恰好是 DDS 和程控衰减器的强项,把资源压在刀刃上,比堆一条全数字链路稳。
2.3 三级架构与模块职责
整体按发射、信道、接收三段切,控制器横跨三段做调度和人机交互。
发射段以四通道 DDS 为核心,通道 0 出载波,通道 1 出本振(供接收端混频),通道 2 留作基带或第二路信号。DDS 之后接低通滤波器压谐波,再进可变增益放大器做幅度粗调,最后经固定衰减器分段、缓冲输出。这一段的关键是「一路信号只在一个地方调幅度」,否则标定会变成多变量拟合。
信道段是模拟衰减网络加数字噪声注入。衰减分两段:可变增益放大器负责 0~40 dB 连续段,继电器或模拟开关切固定衰减器负责大衰减段,两段串联凑出 60 dB 总量程。噪声由 FPGA 产生高斯序列,经 DAC 叠加到基带或中频上,用衰减量反推信噪比,这样信噪比就是可算的,不是靠试。
接收段先混频下变频到中频,再检波、滤波、ADC 采样。检波用对数检波器,输出与被测功率成线性 dB 关系,这是整套方案里最值钱的一颗器件——它把「测幅度」变成了「测直流电压」,12 位 ADC 就能读出 0.03 dB 的分辨率。控制器负责扫频、切换调制、采集检波电压、跑测量算法、刷屏。
三段之间只有两类接口:射频同轴和 SPI/GPIO 控制线。射频线走短、走直、全程 50 Ω;控制线全部串 33 Ω 电阻并远离射频走线。这个约束听起来啰嗦,但联调阶段一半的怪问题都出在控制线串到射频通道上。
3. 硬件链路:发射、衰减与检波三段的增益预算
3.1 发射链路与谐波抑制
DDS 输出是阶梯状近似正弦,频谱里除了主音还有时钟馈通和镜像,直接送出去测谐波一定超标。所以 DDS 后面第一级必须是低通,而且截止频率要卡在主音上限的 1.2 倍左右,不能图省事留太宽。这套方案主音上限 10 MHz,低通截止取 12 MHz,用七阶椭圆滤波器,元件值按 50 Ω 系统算,电感和电容都用 1% 精度,电感选高 Q 的绕线型。
滤波器之后接一级电流反馈运放做缓冲放大,增益 20 dB,作用是补回滤波器的插入损耗并给后面的可变增益级一个合适的输入电平。这里有个容易忽略的点:运放的压摆率要按最高频率和最大幅度算,10 MHz、2 Vpp 正弦需要的最小压摆率是 2π×10M×1V ≈ 63 V/μs,选型时留三倍余量,否则高频段幅度会自己掉下来,你还以为是滤波器的问题。
增益预算我习惯先列表再画板,表算不平就说明架构有问题:
| 级 | 器件角色 | 增益/损耗 | 输出电平 |
|---|---|---|---|
| DDS 输出 | 信号源 | -5 dBm | -5 dBm |
| 低通滤波 | 七阶椭圆 | -1.5 dB | -6.5 dBm |
| 缓冲放大 | 电流反馈运放 | +20 dB | +13.5 dBm |
| 可变增益 | 压控 VGA | -2.5~+42.5 dB | 随控制电压 |
| 固定衰减 | 0/20/40 dB 三段 | 0~-40 dB | 分段 |
| 输出缓冲 | 宽带缓冲器 | 0 dB | 50 Ω 负载 |
按这张表算,最大输出约 +13.5 dBm,扣掉固定衰减还有余量覆盖 2 Vpp(约 +10 dBm)的要求,最小输出靠 VGA 压到 -42.5 dBm 再叠 40 dB 固定衰减,能到 -80 dBm 量级,满足小信号测试。
3.2 程控衰减网络:连续段加分段的组合
衰减网络是这套方案里最容易被低估的部分。纯继电器切固定衰减器,步进是离散的,做不出 1 dB 步进;纯 VGA 连续可调,线性度好但动态范围不够 60 dB。通常的做法是「VGA 管连续、固定衰减管量程」,VGA 的增益控制电压由 DAC 给,固定衰减器由继电器切,控制器里维护一张「目标衰减 → VGA 电压 + 继电器组合」的查找表。
固定衰减器的电阻值不能拍脑袋,按 Π 型网络算,给定衰减量 A 和特性阻抗 Z0:
import math def pi_atten(att_db, z0=50.0): """Π 型衰减器:返回串联臂电阻与两个并联臂电阻(欧姆)""" k = 10 ** (att_db / 20.0) r_series = z0 * (k * k - 1) / (2 * k) # 串联臂 r_shunt = z0 * (k + 1) / (k - 1) # 每个并联臂 return r_series, r_shunt for a in (1, 6, 10, 20): rs, rp = pi_atten(a) print(f"{a:>2} dB: 串联 {rs:7.2f} Ω, 并联 {rp:8.2f} Ω")1 dB 档算出来串联臂只有几欧,并联臂接近 900 Ω,这种值用普通 1% 电阻根本凑不准,实际做法是串联臂用两个电阻并联凑值、并联臂用两个串联凑值,或者干脆把 1 dB 档交给 VGA 做,固定衰减器只做 10 dB、20 dB、40 dB 三档二进制组合。这样每档衰减量大、电阻值好买、误差也好控,1 dB 步进由 VGA 的 DAC 细分出来。
VGA 的增益控制斜率一般是 50 dB/V 这个量级,控制电压 0~1 V 对应 40 多 dB 动态范围。DAC 用 12 位,3.3 V 参考,理论分辨率 0.8 mV,换算到增益是 0.04 dB,做 1 dB 步进绰绰有余。真正的误差来源不是 DAC 分辨率,而是 VGA 增益曲线的非线性,所以每台样机都要做一次全量程标定,把「目标衰减 → DAC 码」写成表烧进 Flash,上电查表。
3.3 对数检波与 ADC 采样
检波用对数检波器,它的输出和输入功率(dBm)成线性关系,典型斜率 25 mV/dB,动态范围 90 dB 以上。这意味着一个 12 位 ADC 覆盖 90 dB 量程,平均每 dB 只分到 0.03 V 不到,但换算成 dB 的分辨率是够的。换算代码很朴素,坑在标定:
/* 对数检波器输出经 12 位 ADC 采样后换算为 dBm * v = adc * VREF / 4095 * Pin(dBm) = (v - Vintercept) / slope * slope 典型 25 mV/dB,Vintercept 约 0.5 V,均需逐台标定 */ typedef struct { float slope_v_per_db; /* 标定得到的斜率 */ float intercept_v; /* 标定得到的截距 */ } det_cal_t; float det_read_dbm(const det_cal_t *cal, uint16_t adc_raw) { float v = adc_raw * 3.3f / 4095.0f; return (v - cal->intercept_v) / cal->slope_v_per_db; }标定用两点法:信号源给 -20 dBm 和 -60 dBm,各读一次 ADC,解二元一次方程得到斜率和截距。要注意检波器的截距电压有温漂,样机在空调房里标完,搬到答辩教室可能偏 0.3 dB,所以固件里留一个「现场零点校准」菜单,用 0 dBm 参考点做单点修正,把截距重新拉回来。这个功能花不了二十行代码,但能救一次现场。
ADC 采样端还有两个细节。一是采样要开多次平均,硬件取 16 次再开方,能把随机噪声压下去 3 dB 左右;二是 ADC 的参考电压必须和 DAC 共用同一颗基准,否则衰减设定值和检波读数值会各漂各的,标定表永远对不上。
3.4 电源与地平面的处理
射频链路的电源噪声会直接变成相位噪声和杂散,这一点在 10 MHz 以下还不太明显,一旦做到几十兆就藏不住了。做法是分区分域:DDS 和运放用低噪声 LDO 单独供电,数字部分用开关电源再经 LC 滤波,模拟地和数字地单点连接,连接点选在 ADC 下方。射频走线全程包地,过孔间距小于最高频率波长的二十分之一,10 MHz 对应波长 30 米,这个条件很宽松,但板子上的走线该短还是要短。
4. 软件实现:DDS 配置、调制与测量算法
4.1 频率与幅度控制字的计算
DDS 的输出频率由频率控制字决定,公式是 FTW = f_out × 2^N / f_sysclk,N 是相位累加器位宽,通常是 32 位。写代码时中间量必须用 64 位,否则频率一高就溢出:
/* DDS 频率控制字计算,32 位相位累加器 */ #define DDS_SYSCLK_HZ 500000000ULL static uint32_t dds_ftw(uint32_t f_out_hz) { /* 先左移 32 位再除,避免 32 位乘法溢出 */ return (uint32_t)(((uint64_t)f_out_hz << 32) / DDS_SYSCLK_HZ); } /* 幅度控制字:满幅 1023,按 10 位换算 */ static uint16_t dds_asf(float ratio) { if (ratio > 1.0f) ratio = 1.0f; if (ratio < 0.0f) ratio = 0.0f; return (uint16_t)(ratio * 1023.0f); }500 MHz 系统时钟下,一个 FTW 步进对应 0.116 Hz,做 1 kHz 步进时取整误差可以忽略。但如果系统时钟只有 100 MHz,步进就变成 0.023 Hz,仍然够用,代价是相位噪声和杂散变差。选时钟时不要只看分辨率,要看相噪指标,分辨率富余太多没有意义。
幅度控制字这里要注意:DDS 内部的幅度乘法器是数字的,直接改 ASF 做 AM 会有量化台阶,1 kHz 调制、100 kSPS 更新率,一个周期只有 100 个点,包络看起来会有锯齿。通常的做法是 AM 用外部模拟乘法器做,DDS 只负责出干净载波;ASK 才用 DDS 内部幅度切换,因为 ASK 只有两个状态,不怕台阶。
4.2 四种调制方式的寄存器级实现
AM 走模拟乘法器:DDS 出载波进乘法器一端,基带正弦(由第二路 DDS 或 DAC 产生)进另一端,调制深度靠基带幅度调。m = 0 时基带幅度为 0,输出纯载波;m = 100% 时基带峰值等于载波幅度,包络最小点接近零。乘法器的输出要加隔直和低通,把基带泄漏滤掉。
FM 走频率字更新:定时器按 1 MSPS 触发,每次中断算一次瞬时频率 f = f0 + Δf·sin(2πf_m·t),写进 DDS 频率寄存器。1 MSPS 更新率对 1 kHz 基带是 1000 点一周期,量化噪声在 -60 dBc 以下,够用。更新率再低就会听到咔哒声,频谱上表现为边带杂散。
ASK 走 profile 切换:DDS 一般有多个 profile 寄存器,预存「有载波」和「无载波」两组频率/幅度,用引脚电平切换,切换时间在纳秒级,做 1 kbps~100 kbps 的 ASK 毫无压力。
FSK 同样走 profile,两个 profile 存 f0 和 f1,切换由基带方波驱动。关键是两个 profile 的相位要连续,否则切换瞬间相位跳变会让频谱展宽。
4.3 噪声与多径的数字化模拟
信道里要加噪声,用 FPGA 产生高斯白噪声最方便。均匀随机数经 Box-Muller 变换成高斯分布,再乘一个可调的 σ 控制噪声功率:
/* Box-Muller:两路均匀分布转高斯分布,返回定点噪声样本 */ static int32_t gauss_sample(int32_t sigma) { /* 取 24 位有效位并加极小值,防止 log(0) */ float u1 = (rand_u32() >> 8) * (1.0f / 16777216.0f) + 1e-7f; float u2 = (rand_u32() >> 8) * (1.0f / 16777216.0f); float g = sqrtf(-2.0f * logf(u1)) * cosf(6.2831853f * u2); return (int32_t)(g * sigma); }σ 的大小不靠试,由目标信噪比反算:信号功率已知(由衰减设定值算),噪声功率 = 信号功率 / SNR,σ 再按 DAC 满幅折算。这样上位机输入「25 dB 信噪比」,固件直接算 σ,测出来的 SNR 误差能控制在 1 dB 内。
多径在数字域做更省事:一片双口 RAM 当延迟线,写指针和读指针差可调,模拟 0.5 μs~10 μs 的延迟;读出后乘一个衰减系数(模拟反射强度),再和主路相加。两径模型就够应付大部分题目要求,三径只是多加一路。模拟域做多径要用声表延迟线,器件贵且延迟固定,不划算。
4.4 测量算法:过零测频、包络测深、FFT 算信噪比
频率测量最省资源的是过零检测:ADC 采一段信号,数上升沿过零点的间隔,用采样率除以平均周期。10 MHz 信号、100 MSPS 采样,一个周期 10 个点,过零插值后误差能到 0.1% 以内。代码里要注意加迟滞,否则噪声会让过零点抖出一堆假计数。
调制深度用包络算:检波输出经 ADC 采样,找一段包络的最大值 Vmax 和最小值 Vmin,m = (Vmax - Vmin) / (Vmax + Vmin)。采样窗要覆盖至少三个基带周期,否则极值找不全。这个方法对 AM 有效,对 FM 要先鉴频再算。
信噪比用 FFT 算:采 4096 点做窗函数加 FFT,信号功率取主瓣内功率和,噪声功率取带内总功率减信号功率。加汉宁窗能把频谱泄漏压到 -31 dB 以下,对 40 dB 的 SNR 测量够用。这套算法在 STM32 上用单精度浮点跑 4096 点大约几十毫秒,刷新率够看。
4.5 定时调度与状态机
固件按前后台结构写:主循环跑状态机和人机界面,定时器中断跑实时性要求高的任务(FM 频率更新、噪声样本输出),DMA 负责 ADC 采样搬运。状态机分待机、单音、调制、扫描四个状态,状态切换时统一调用一个apply_config()把频率、幅度、衰减、调制参数一次性写下去,避免中途出现半新半旧的配置。这个习惯是从一次翻车里养成的:早期版本切调制方式时先改频率后改幅度,中间有几十微秒输出满幅,把后面的检波器前端吓一跳。
5. 避坑与排查:联调阶段最容易翻车的五个点
5.1 输出谐波超标,频谱仪上一排尖刺
现象:主音 10 MHz,频谱上 20 MHz、30 MHz 处各有一根明显的尖刺,二次谐波只比主音低 20 dB 出头。
原因:低通滤波器截止频率留太宽,或者电感用了普通贴片电感、Q 值太低,高频段衰减不够。还有一种情况是 DDS 的时钟馈通从电源串出去,表现为固定的时钟频率及其分频点。
解决:把低通截止压到主音上限的 1.2 倍,换高 Q 绕线电感,滤波器前后各加一级 LC 去耦;时钟馈通靠屏蔽和地平面处理,DDS 的电源脚旁边放 0.1 μF 和 10 pF 并联,10 pF 专门旁路高频。改完再测,二次谐波能压到 -45 dBc 以下。
5.2 衰减器切换瞬间输出跳变甚至自激
现象:从 0 dB 切到 20 dB,示波器上看到一个几十微秒的过冲,偶尔还会持续振荡。
原因:继电器切换有机械抖动,触点在断开瞬间处于悬空状态,射频通路阻抗失配引起反射;如果用的是模拟开关,导通电阻随温度变化,切换瞬间增益突变。
解决:改成「先切后断」的顺序——先让 VGA 把增益压下去 10 dB,再切继电器,切完把 VGA 补回来,用固件掩盖机械动作;或者换固态继电器,切换时间短、无抖动。另外在衰减网络两端各加一个 50 Ω 匹配电阻到地,让悬空期间也有确定的阻抗。
5.3 检波读数随温度漂,早上标定下午就不准
现象:同一台样机,上午标的 0 dBm 对应 1.05 V,下午变成 1.02 V,误差 0.5 dB 以上。
原因:对数检波器的截距电压有温度系数,机箱内温度随功放发热上升十几度,截距就漂了。
解决:固件里加现场校准入口,用一路参考信号(DDS 直接给 0 dBm)做单点修正,把截距拉回来;硬件上把检波器远离发热器件,必要时贴一小片铜箔均温。更彻底的做法是双点校准,同时修正斜率和截距,但要占两个信号源档位,看现场时间够不够。
5.4 加调制后解调波形失真,示波器上看像削顶
现象:AM 调制深度设到 80%,解调输出正弦波顶部和底部都平了。
原因:乘法器输入超出线性范围,或者基带信号本身带直流偏置。乘法器的输出幅度和两路输入幅度成正比,载波幅度调大之后,调制深度 80% 时峰值已经接近供电轨。
解决:在乘法器前把载波幅度压到满幅的 60%,把余量留给调制;基带通路加隔直电容,确保偏置为零;如果还削顶,检查乘法器的输出负载电阻是否合适,输出电流能力不够也会削顶。
5.5 数字噪声串进射频通道,小信号测不准
现象:输出 -70 dBm 小信号时,频谱底噪比理论值高 10 dB,关掉控制器时钟底噪就下来。
原因:SPI 时钟线和射频走线平行走了很长一段,串扰耦合进通道;或者数字地和模拟地共用一段,地弹把噪声注进检波器。
解决:SPI 线串 33 Ω 电阻并加地线包夹,走线远离射频区;模拟地和数字地单点连接,连接点放在 ADC 下方;检波器输出到 ADC 的走线尽量短,中间加 RC 低通,截止频率取采样率的十分之一。改完底噪能降 8 dB 左右。
6. 联调与答辩:把指标验收做成一张可复现的测试表
6.1 自测清单与判定方法
联调阶段最忌讳「感觉差不多了」就去答辩。我的做法是照第 2 章的指标表做一张测试记录表,每一项写清测试条件、仪器设置、判定门限,测完填数、签字。表里必须有测试条件这一列,因为同一个指标在不同频率、不同幅度下结果不一样,只写一个数没有意义。
| 测试项 | 测试条件 | 仪器设置 | 判定门限 |
|---|---|---|---|
| 频率误差 | 100 kHz / 1 MHz / 10 MHz 三点 | 频率计,闸门 1 s | ≤1% 或 ±1 kHz |
| 衰减线性 | 0~60 dB,每 1 dB 一点 | 频谱仪,RBW 1 kHz | 每点误差 ≤1 dB |
| 谐波抑制 | 10 MHz 满幅输出 | 频谱仪,扫到 50 MHz | 二次谐波 ≤-40 dBc |
| 调制深度 | AM 30%/60%/90% | 示波器,包络测量 | 误差 ≤5% |
| 解调失真 | 1 kHz 基带,60% 深度 | FFT,看 2~5 次谐波 | THD ≤5% |
| 信噪比 | 设定 10/20/30 dB | 频谱仪读信噪比 | 误差 ≤2 dB |
跑这张表要留足半天,从低频到高频、从小信号到大信号逐点扫。扫的过程中大概率会发现某几个频点误差超标,这时候别急着改硬件,先看误差是不是规律性的——等间隔偏移多半是标定表的问题,随机跳变才是硬件问题。
6.2 答辩怎么讲才不被打断
答辩时间通常很短,讲法比内容更重要。我一般按四段讲:第一段讲指标拆解,说明这道题的核心是把功能翻译成可测量,一句话带过;第二段讲架构,用手画的框图讲清三级分工,重点强调「幅度只在一个地方调」这个设计决策;第三段讲难点,挑一到两个真踩过的坑,讲现象、原因、怎么解决的,这段最能体现水平;第四段放实测数据,直接把测试表投出来,让评委看数字。
讲的时候有两件事不要做。一是不要念代码,评委不关心你的 SPI 怎么写,关心的是你为什么这么选;二是不要藏问题,指标有超差的地方主动说清楚边界条件,比被问出来强。有一次我在答辩现场被问到低温下的衰减误差,因为提前做过降温测试并记录了数据,直接翻到那一页就过了。
从那以后我每次做射频类项目,都强制先跑一遍全量程标定再动手改电路,标定表不出来不动烙铁。这套方案的架构图、增益预算表、寄存器配置和测试记录我整理成了一份可以直接当模板改的文档,按章节标题就能对上你手上的题面,需要拿去对照的按这个结构改就行。希望帮到你。
本文还有配套的精品资源,点击获取