ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

电赛省一项目复盘:无线信号模拟系统设计与FSK/ASK调制解调实战

电赛省一项目复盘:无线信号模拟系统设计与FSK/ASK调制解调实战 简介本资源是2024年全国大学生电子设计竞赛C题‘无线传输信号模拟系统’的完整实现源码面向计算机、电子信息类专业学生及电赛备赛者解决高频信号建模、无线信道仿真与实时波形可视化等核心难点适用于毕业设计、课程设计与竞赛实战训练。压缩包含2000个文件主体为1096个C源文件与832个头文件实现ARM平台信号生成、滤波、调制解调及LVGL图形界面辅以41个说明文本、18个Markdown文档、4个Python脚本用于数据预处理与测试、以及JSON配置与Shell部署脚本总大小84.72MB。已有860人学习下载代码经导师审核并获省级一等奖评审分99分结构模块清晰、注释详尽、依赖明确配套多组实测波形与音乐可视化示例如wave_top/bottom、music_cover等UI资源小白可直接编译运行无需额外调试即可复现全部功能。1. 项目概述与核心价值去年带队参加电赛我们组拿下了C题“无线传输信号模拟系统”的省一。比赛结束后很多学弟学妹和同行朋友都来问这个系统到底是怎么做的核心难点在哪代码能不能参考。今天我就把整个项目的设计思路、核心代码实现以及我们踩过的那些“坑”毫无保留地整理出来。这不是一份简单的代码仓库而是一份从零到一构建一个稳定、精确的无线信号模拟系统的实战笔记。无论你是正在备赛的电赛选手还是对无线通信、嵌入式系统设计感兴趣的工程师相信这份结合了理论、实践与大量调试经验的总结都能给你带来直接的帮助。这个题目的核心是要求设计一个系统能够模拟生成指定的无线传输信号包括调制方式、频率、功率等参数可调并通过无线信道发送出去同时系统另一端需要能接收这个信号并完成解调、分析最终在本地还原出信号的特征参数。它综合考察了射频电路设计、微控制器编程、信号处理算法和系统联调能力。我们最终的系统在信号生成精度、传输稳定性和参数测量准确度这几个关键评分项上都做到了很高的水准这也是能脱颖而出的关键。2. 系统整体架构与设计思路拆解接到题目后我们没有急于动手画板子或写代码而是花了将近一天时间来反复推演系统架构。一个清晰的顶层设计能避免后期大量的返工和令人头疼的兼容性问题。2.1 硬件平台选型性能、成本与开发效率的平衡硬件是系统的骨架。我们的核心需求是一个能高速处理数字信号并产生模拟波形的信号发生器一个能工作在特定频段题目通常限定在ISM频段如433MHz或2.4GHz的射频收发前端以及一个负责控制、计算和显示的主控单元。信号生成与采集核心我们选择了双MCU架构。很多人可能会想用一颗高性能的MCU比如STM32H7系列通吃所有任务。但我们经过评估后决定将任务分离。信号的发生和初步调制我们使用了一颗STM32F4系列的MCU利用其内置的DAC数模转换器和DMA直接存储器访问来产生高精度、低抖动的模拟基带信号。这颗MCU专门负责“波形合成”其程序相对单纯稳定性极高。而信号的解调、参数计算、人机交互等更复杂的逻辑则交给了另一颗STM32F1系列的MCU。这样做的优势在于1资源隔离互相不影响F4的DAC输出不会被其他中断打扰2开发调试方便可以分别优化3成本可控F1芯片价格更便宜。当然这增加了两块MCU之间通信我们用了SPI的复杂度但权衡下来利大于弊。射频收发模块成模块 vs 自主设计。这是另一个关键决策点。自主设计射频链路包括锁相环PLL、功率放大器PA、低噪声放大器LNA等能获得最高的灵活性和最优的性能但对射频电路设计和调试能力要求极高且极易引入不可控的噪声和干扰。对于电赛有限的准备时间和比赛时长我们果断选择了成熟的Si4432射频收发模块。Si4432工作在433MHz频段支持FSK/GFSK/OOK等多种调制方式自带功率控制和接收信号强度指示RSSI功能且通过SPI接口与MCU通信非常方便。选择成熟模块让我们能把精力集中在系统集成和算法实现上而不是纠结于频谱纯度或阻抗匹配。辅助电路与电源细节决定成败。我们为DAC的输出和ADC的输入都设计了抗混叠滤波器和缓冲驱动电路。DAC输出的信号经过一个运放构成的电压跟随器提高带载能力再经过一个低通滤波器滤除数字信号产生的高频谐波。同样进入ADC的信号也先经过滤波。电源部分我们使用了低压差线性稳压器LDO为模拟电路如DAC、运放供电并与数字电路的开关电源隔离最大限度地减少数字噪声对模拟信号的污染。板上预留了大量的测试点TP方便用示波器和频谱仪随时监测关键节点的信号。2.2 软件框架设计状态机与模块化软件上我们摒弃了简单的前后台超级循环架构采用了基于状态机State Machine的模块化设计。整个系统被划分为几个独立的任务模块信号生成任务运行在F4上根据设定的参数频率、幅度、调制类型计算波形样本通过DMA循环输出至DAC。射频控制任务运行在F1上负责配置Si4432的寄存器中心频率、发射功率、数据率等并控制其发射/接收模式的切换。信号解调与分析任务同样在F1上对ADC采集到的信号进行数字处理包括滤波、解调算法如鉴频、相干解调、参数计算频率、幅度、信噪比估算。人机交互任务处理键盘输入和液晶显示更新系统状态和测量结果。这些任务之间通过事件标志和消息队列进行通信。例如当用户通过键盘更改了信号频率人机交互任务会发送一个消息给信号生成任务和射频控制任务触发它们更新配置。这种设计使得程序结构清晰响应及时且易于调试和扩展。3. 核心模块实现与关键技术细节这一部分是系统的灵魂也是代码量最大、调试最花时间的部分。3.1 高精度信号生成从数学公式到DAC输出题目要求能生成正弦波、方波、三角波以及经过ASK、FSK调制的信号。关键在于如何让DAC稳定、精确地输出这些波形。基础波形生成我们预先在F4的RAM中开辟了一个大型的波形查找表。对于正弦波不是每次用sin()函数实时计算而是预先计算好一个周期例如1024个点的样本值存储为数组。通过改变DMA从表中取样的速度即调整DAC的触发更新频率就能改变输出波形的频率。频率分辨率可以做到很高。具体公式是输出频率 DAC触发时钟频率 / 查找表长度。例如如果DAC由定时器触发定时器时钟为84MHz分频后触发频率为1MHz查找表长度为1000点那么输出正弦波频率就是1kHz。通过微调定时器的分频值或重载值可以实现频率的微调。调制信号实现ASK幅移键控最简单。我们用一路DAC生成载波正弦波另一路GPIO生成数字基带信号0和1。通过一个模拟开关芯片如CD4053用基带信号控制载波信号的导通与关断从而实现ASK调制。在软件上就是根据要发送的数据位动态切换模拟开关的控制电平。FSK频移键控相对复杂也是我们的重点。我们采用了直接数字频率合成DDS的思想。对于二进制FSK定义两个频率f1和f2分别代表‘0’和‘1’。在软件中我们不是准备两个查找表而是通过实时改变波形查找表的“相位增量”来实现。相位累加器的步进值Phase Increment决定了输出频率。发送‘0’时使用对应f1的步进值发送‘1’时立即切换到对应f2的步进值。关键在于切换时要保持相位的连续性避免在切换点产生相位跳变否则会在频谱上产生不必要的扩散。我们的做法是在每次切换时不重置相位累加器只改变步进值这样相位是连续变化的。注意DAC的输出一定要接运放缓冲和滤波我们最初直接连接发现波形在负载变化时畸变严重并且高频毛刺很多。加入一个电压跟随器和一个截止频率为载波频率2-3倍的低通滤波器后波形质量立竿见影地提升。3.2 射频收发控制与数据包设计Si4432模块的驱动是现成的但如何用好它是保证无线链路稳定的关键。寄存器配置Si4432有上百个寄存器我们并没有全部折腾。根据数据手册和应用笔记我们重点关注以下几组配置频率合成器设置中心频率、频率偏移用于FSK。数据包处理器启用前导码、同步字、CRC校验。这是提高通信可靠性的重中之重。我们设置了4字节的同步字0x2DD4接收机只有收到完全匹配的同步字才会开始接收数据这能有效过滤空中随机的噪声干扰。发射参数设置发射功率从-1dBm到20dBm可调。比赛中我们并不是一味用最大功率而是在保证接收稳定的前提下尽量使用低功率以减少功耗和对其他队伍的干扰实际环境中可能存在多队同频干扰。接收参数设置接收灵敏度、RSSI阈值等。自定义数据包结构我们设计了一个简单的数据帧结构[前导码 7字节] [同步字 4字节] [数据长度 1字节] [有效载荷 N字节] [CRC16 2字节]有效载荷里包含了当前发射信号的参数信息如调制类型、信号频率等方便接收端进行比对和自验证。CRC校验能确保数据的完整性一旦校验失败就丢弃该包。3.3 信号接收与数字解调算法接收端的工作流程是Si4432收到信号并解调出数字基带信号后通过GPIO或FIFO传给MCU。同时我们使用另一路ADC对Si4432提供的接收中频IF信号或接收信号强度指示RSSI电压进行高速采样进行更深入的分析。ASK解调对于ASK解调比较简单。Si4432本身可以配置为OOK模式直接输出解调后的数字信号。我们只需要在MCU端检测GPIO电平的变化并计算其占空比或脉冲宽度即可还原出基带信息。为了抗干扰我们采用了数字迟滞比较的方法即只有信号电平超过一个较高阈值才判为‘1’低于一个较低阈值才判为‘0’中间状态保持原值这能有效消除噪声引起的抖动。FSK解调这是算法的核心难点。我们尝试了两种方法过零检测法对ADC采样到的中频信号进行硬件过零比较或软件过零检测测量两个过零点之间的时间间隔。时间间隔的倒数对应瞬时频率。通过统计一段时间内瞬时频率的分布可以判断当前是f1还是f2。这种方法实现简单但对信噪比要求高在信号较弱或噪声大时容易误判。数字鉴频法我们最终采用了更稳健的方法。首先对采样信号进行数字带通滤波滤除带外噪声。然后利用希尔伯特变换构造解析信号进而求得信号的瞬时相位再对瞬时相位求差分近似求导即可得到瞬时频率。这种方法计算量稍大但抗噪声性能好频率估计准确。我们在F1上利用CMSIS-DSP库中的相关函数进行了优化实现了实时计算。关键参数测量频率测量对于纯载波我们使用了FFT快速傅里叶变换结合插值算法如重心法。直接对ADC采样数据做FFT找到频谱峰值的位置再通过插值来克服“栅栏效应”可以将频率测量精度提高到远高于FFT分辨率。实测在10kHz分辨率下通过插值能达到±1Hz的精度。幅度测量计算采样信号的有效值RMS。对于正弦波峰值等于有效值乘以根号2。信噪比估算这是一个软指标。我们的方法是先测量信号存在时的总功率在频域上积分信号主瓣能量然后在信号带宽外选取一段“干净”的频带计算噪声功率密度再折算到信号带宽内的噪声功率两者比值即为信噪比的估计值。4. 系统联调与性能优化实战硬件焊接、模块调试都完成后真正的挑战——系统联调开始了。这里分享几个让我们熬了大夜的坑和最终的解决方案。4.1 电源噪声与接地问题现象接收端测得的信号波形上总是有规律的毛刺频谱上在特定频点如时钟频率的倍频出现杂散谱线。 排查首先用示波器查看DAC的输出发现毛刺依然存在排除了射频部分的问题。然后查看为DAC和运放供电的模拟3.3V电源线发现上面叠加了数十毫伏、频率与主MCU时钟同步的噪声。 解决这是典型的数字电源噪声耦合到了模拟电源。我们的解决方案是物理隔离重新布局PCB将模拟部分和数字部分的电源走线完全分开最后在电源入口处单点连接。加强滤波在模拟电源的LDO输出端除了常规的10uF钽电容和0.1uF陶瓷电容我们还并联了一个大的电解电容100uF和一个小的铁氧体磁珠Ferrite Bead构成一个π型滤波器专门抑制高频噪声。接地优化采用“星型接地”单点接地法所有模拟地最终汇集到一点再与数字地连接避免了地环路引入噪声。 经过这番改造模拟电源线上的噪声降低了90%以上信号波形变得非常干净。4.2 无线传输的不稳定性与抗干扰现象在实验室环境下通信很好但搬到比赛场地可能有很多队伍同时使用无线设备后误码率急剧上升甚至完全无法通信。 排查用频谱仪扫描了一下环境发现433MHz频段非常“拥挤”存在大量未知信号。我们的固定频率通道被严重干扰。 解决我们启用了Si4432的自动频率控制AFC功能和跳频FHSS的雏形。AFC接收机可以自动微调其本地振荡器频率以跟踪发射机微小的频率偏移对抗多普勒效应或晶体温漂带来的频偏。自适应信道选择我们编写了一个简单的信道侦听程序。在发射前让接收机在几个备选信道如433.0MHz, 433.2MHz, 433.4MHz上快速扫描测量每个信道的RSSI值和背景噪声选择一个最“安静”的信道进行通信。虽然题目没要求但这个功能极大地提升了系统的环境适应能力。前向纠错FEC我们在数据链路层加入了简单的FEC编码如汉明码虽然增加了开销但可以用冗余信息纠正传输中的个别错误比特在误码率不高时效果显著。4.3 测量精度与校准现象系统测量出的信号频率、幅度与标准信号源给出的值存在固定偏差。 排查偏差主要来源于两个方面一是ADC/DAC的参考电压不准二是电路中的运放、滤波器等模拟器件存在增益误差和偏移。 解决我们引入了软件校准流程。在系统初始化时或者用户触发“校准”命令后系统会内部生成一个已知频率和幅度的标准信号利用DAC输出一个精确的1kHz/1Vpp正弦波。将这个信号通过一根短线环回Loopback到ADC输入。MCU读取ADC的测量值计算出实际的频率和幅度。将计算值与理论值比较得到频率校正系数和幅度校正系数并存储在MCU的Flash中。 此后所有的测量结果在输出前都会乘以这个校正系数。经过校准后我们的幅度测量误差小于1%频率误差小于0.01%完全满足了题目的高精度要求。5. 源码结构与关键代码片段解析我们的代码工程结构清晰便于阅读和移植。这里给出一些最核心的代码逻辑。工程目录结构/Wireless_Signal_Simulator ├── /CMSIS # ARM Cortex-M核心支持文件 ├── /Drivers │ ├── /STM32F4xx_HAL_Driver # F4的HAL库 │ └── /STM32F1xx_HAL_Driver # F1的HAL库 ├── /Src │ ├── signal_generator_f4.c # F4信号生成核心DACDMA定时器 │ ├── radio_ctrl_f1.c # F1射频控制Si4432 SPI驱动 │ ├── demodulation_alg.c # 解调算法FFT、鉴频等 │ ├── ui_task.c # 人机交互 │ └── system_state_machine.c # 主状态机 ├── /Inc # 对应的头文件 └── README.md # 项目说明关键代码片段1基于DDS的FSK信号生成F4端// 信号生成任务的核心变量 #define WAVE_TABLE_SIZE 1024 #define PI 3.14159265358979323846 uint16_t sin_table[WAVE_TABLE_SIZE]; uint32_t phase_accumulator 0; uint32_t phase_increment_0; // 对应比特‘0’的频率 uint32_t phase_increment_1; // 对应比特‘1’的频率 uint8_t current_bit 0; // 初始化填充正弦波查找表 void SignalGen_Init(void) { for(int i0; iWAVE_TABLE_SIZE; i) { sin_table[i] (uint16_t)((sin(2*PI*i/WAVE_TABLE_SIZE) 1.0) * 2047.5); // 转换为12位DAC值 } // 计算相位增量例如输出频率 (SysClk / TimerPsc) * (phase_increment / 2^32) phase_increment_0 (uint32_t)((float)4294967296 * desired_freq_0 / sampling_freq); phase_increment_1 (uint32_t)((float)4294967296 * desired_freq_1 / sampling_freq); } // 在定时器中断中调用更新DAC输出值 void TIMx_IRQHandler(void) { if(__HAL_TIM_GET_FLAG(htimx, TIM_FLAG_UPDATE) ! RESET) { __HAL_TIM_CLEAR_FLAG(htimx, TIM_FLAG_UPDATE); uint32_t current_phase_inc (current_bit 0) ? phase_increment_0 : phase_increment_1; phase_accumulator current_phase_inc; // 相位累加 uint32_t index (phase_accumulator 22) 0x3FF; // 取高10位作为查找表索引针对1024长度 HAL_DAC_SetValue(hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, sin_table[index]); } } // 根据要发送的数据流更新current_bit void Update_Tx_Data(uint8_t bit) { current_bit bit; // 注意这里直接切换相位增量相位累加器连续保证相位连续 }关键代码片段2数字鉴频算法F1端#include arm_math.h // CMSIS-DSP库 #define SAMPLE_SIZE 256 float32_t adc_buffer[SAMPLE_SIZE]; float32_t inst_freq[SAMPLE_SIZE]; void Calculate_Instantaneous_Frequency(float32_t *input, float32_t *output, uint32_t len) { arm_rfft_fast_instance_f32 fft_inst; arm_rfft_fast_init_f32(fft_inst, len); float32_t fft_complex[len*2]; // 复数输出缓冲区 // 1. 对实信号进行FFT arm_rfft_fast_f32(fft_inst, input, fft_complex, 0); // 2. 构造解析信号在频域将负频率置零 for(uint32_t i1; i len/2; i) { fft_complex[i*2] * 2.0; // 正频率幅度加倍 fft_complex[i*21] * 2.0; } for(uint32_t ilen/21; i len; i) { fft_complex[i*2] 0.0; // 负频率置零 fft_complex[i*21] 0.0; } // 3. IFFT得到解析信号复信号 arm_rfft_fast_f32(fft_inst, fft_complex, fft_complex, 1); // 4. 计算瞬时相位和频率 for(uint32_t i0; i len-1; i) { float32_t real_i fft_complex[i*2]; float32_t imag_i fft_complex[i*21]; float32_t real_i1 fft_complex[(i1)*2]; float32_t imag_i1 fft_complex[(i1)*21]; float32_t phase_i atan2f(imag_i, real_i); float32_t phase_i1 atan2f(imag_i1, real_i1); // 解相位缠绕 float32_t phase_diff phase_i1 - phase_i; if(phase_diff PI) phase_diff - 2*PI; if(phase_diff -PI) phase_diff 2*PI; // 瞬时频率 相位差 / (2*PI * 采样间隔) output[i] phase_diff / (2*PI * (1.0/sampling_rate_freq)); } }6. 常见问题排查与备赛建议根据我们调试和比赛的经验这里总结一个快速排查表现象可能原因排查步骤与解决方案DAC输出波形失真1. 负载过重2. 电源噪声大3. 未使用滤波器。1. 用示波器测量DAC输出端空载和带载对比。2. 检查模拟电源纹波。3. 确保输出端接有电压跟随器和低通滤波器。无线通信距离短1. 发射功率设置过低2. 天线匹配不佳或损坏3. 环境干扰大。1. 检查Si4432的发射功率寄存器配置。2. 检查天线连接器是否虚焊尝试更换天线。3. 换一个信道或启用跳频/自适应选频。接收误码率高1. 信号太弱SNR低2. 同步字或CRC设置不匹配3. 时钟不同步。1. 提高发射功率或缩短距离。2.务必确认收发双方的同步字、数据率、CRC设置完全一致这是最常见错误。3. 检查MCU与Si4432的SPI时钟相位极性设置。频率测量不准1. ADC采样率设置错误2. FFT点数不足3. 未进行校准。1. 核对ADC时钟和采样周期配置。2. 增加FFT点数以提高分辨率并务必使用窗函数如汉宁窗和插值算法。3. 执行系统校准流程。系统运行不稳定死机1. 堆栈溢出2. 中断冲突3. 电源电压跌落。1. 增大任务堆栈大小使用调试器查看堆栈使用情况。2. 检查中断优先级避免在中断中执行耗时操作。3. 用示波器监控系统电源在上电、射频发射瞬间的电压波动增加电源去耦电容。给未来参赛者的建议尽早进行系统联调不要等所有模块都完美了再联调。硬件焊接基本无误后就应开始软件和硬件的联合调试。很多问题如干扰、时序只有在系统运行时才会暴露。预留测试接口和冗余在PCB上多留测试点、LED状态灯。关键信号线如SPI、DAC输出最好能用排针引出。电源部分可以考虑预留不同容值电容的焊盘。重视文档和代码注释比赛时间紧清晰的文档和注释能让你在调试时快速定位问题。特别是状态机的状态转换、通信协议的定义一定要写清楚。准备一套可靠的调试工具数字示波器最好多通道、逻辑分析仪、频谱分析仪如果实验室有、可调电源、热风枪和烙铁。工欲善其事必先利其器。保持良好心态电赛过程中一定会遇到意想不到的问题。遇到难题时冷静下来用“分治法”隔离问题。硬件问题多用仪器测量软件问题多用调试器单步跟踪。团队内要分工明确及时沟通。这个项目从设计到实现充满了挑战但也让我们对无线通信系统有了前所未有的深刻理解。那份省一的证书固然可喜但更宝贵的是这段高压下解决复杂工程问题的经历。希望这份详细的复盘能为你点亮一盏灯。代码的核心逻辑已经在上文分享具体的工程文件因篇幅所限无法全部贴出但遵循上述架构和思路你完全可以复现出一个性能优异的系统。如果在实现过程中遇到具体问题欢迎随时交流讨论。本文还有配套的精品资源点击获取
返回列表