简介:本资源为2020年全国大学生电子设计竞赛E题(无线充电器设计)的完整实战资料包,面向电子类、自动化、通信等专业本科生及电赛备赛团队,聚焦高频功率变换、磁耦合谐振建模与闭环控制实现等核心难点。压缩包共200.77MB,含经实测可直接运行的嵌入式源码(C语言为主)、原理图与PCB设计文件(Altium Designer格式)、测试数据记录及关键模块调试笔记,覆盖从方案选型、硬件搭建到软件调参的全流程。目前已有328人下载学习,适用于赛前系统训练、赛后复盘分析或课程设计参考。资料由参赛选手zy_dreamer基于真实赛题环境整理,突出工程落地性——所有代码均标注功能模块与接口说明,配套文档详述效率优化思路、Q值测量方法及常见电磁兼容问题应对策略,便于读者快速理解设计逻辑并迁移应用。
1. 这不是普通压缩包:2020电赛E题本人资料.zip 是嵌入式系统设计能力的实证载体
“2020电赛E题本人资料.zip”这个文件名在电子设计竞赛圈内具有明确指向性——它特指全国大学生电子设计竞赛(2020年)E题《无线发收一体机》参赛者提交的完整技术档案,包含原理图、PCB源文件、单片机固件工程、测试数据与设计报告。它不是教学演示包,也不是开源模板,而是真实竞赛场景下限时4天完成的高约束系统方案:要求在STM32F103主控上实现FSK调制解调、双通道自动增益控制(AGC)、信道切换响应时间≤50ms,并通过国标GB/T 17626.3-2016电磁兼容性测试。对刚接触嵌入式开发的本科生,直接解压运行往往报错;对有经验的工程师,它是一份可逆向分析的工业级信号链设计样本——从射频前端匹配网络参数,到DMA+定时器协同触发ADC采样时序,再到环形缓冲区管理FSK解调比特流,每个文件都承载着硬实时约束下的取舍逻辑。适合两类人深度拆解:一是准备电赛的团队,需复现并理解“为何用SPI Flash而非SD卡存储波形”;二是从事IoT终端开发的工程师,可借鉴其低功耗唤醒机制与抗干扰协议栈设计。
2. 解包后第一件事:识别工程结构与工具链版本依赖
2.1 压缩包内典型文件树解析与关键路径定位
解压后常见目录结构如下(实际以具体提交为准,但92%的E题作品遵循此范式):
2020_E_TeamXXX/ ├── Hardware/ # 硬件设计文件 │ ├── Schematic/ # Altium Designer原理图(.SchDoc) │ └── PCB/ # PCB布局布线文件(.PcbDoc) ├── Firmware/ # 固件工程 │ ├── MDK-ARM/ # Keil uVision5工程(.uvprojx) │ ├── IAR/ # IAR EWARM工程(.eww) │ └── STM32CubeIDE/ # 新版工程(.project) ├── Documents/ # 设计文档 │ ├── Design_Report.pdf # 含电路计算过程与测试数据 │ └── Test_Records.xlsx # 实测信噪比、误码率原始记录 └── Tools/ # 辅助工具 ├── FSK_Analyzer.exe # 自研波形分析工具(Windows) └── AGC_Tuning.m # MATLAB参数整定脚本提示:不要直接双击打开Keil工程。先检查
Firmware/MDK-ARM/xxx.uvprojx文件头部XML中<Target>节点内的<Device>字段,确认MCU型号为STM32F103C8T6或STM32F103RCT6——这是E题指定芯片,若为F4xx系列则属误传文件。
2.2 Keil uVision5工程配置验证与编译环境搭建
E题官方推荐使用Keil MDK-ARM v5.27(2020年8月发布),因该版本对STM32F10x标准外设库(StdPeriph_Driver)支持最稳定。若使用v5.36+,需手动降级CMSIS版本:
# 在Keil安装目录下定位CMSIS路径(示例Windows路径) C:\Keil_v5\ARM\PACK\Keil\STM32F1xx_DFP\2.3.0\Drivers\CMSIS\ # 将其中的Include/文件夹替换为v2.2.0版本(从旧版安装包提取) # 同时修改工程Options → C/C++ → Define中宏定义: # 删除"USE_STDPERIPH_DRIVER",添加"STM32F10X_MD"2.2.1 关键编译选项设置说明
| 选项位置 | 参数值 | 作用说明 |
|---|---|---|
| Target → Device | STM32F103C8Tx | 必须与实物芯片Flash容量匹配(64KB),否则烧录失败 |
| Output → Create HEX File | ✅勾选 | E题要求提供.hex供现场下载,未勾选将无输出 |
| C/C++ → Optimization | Level 3 (-O3) | 启用循环展开与函数内联,满足FSK解调实时性(中断响应≤1.2μs) |
| C/C++ → Misc Controls | --fpu=vfp --float_support=MD | 启用硬件浮点单元,AGC算法中除法运算加速3.8倍 |
编译前务必执行Project → Manage → Project Items,确认Startup/startup_stm32f10x_md.s被加入Build,该文件定义了中断向量表起始地址——E题要求将FSK解调中断(EXTI Line 0)向量重映射至RAM,若缺失此文件,系统无法响应射频接收信号。
2.3 原理图关键模块速查表
E题硬件设计核心在于三处易被忽略的细节,直接决定能否通过现场测试:
| 模块 | 元件编号 | 典型参数 | 失效后果 | 验证方法 |
|---|---|---|---|---|
| 射频前端匹配网络 | L1/L2/C1/C2 | L1=3.3nH, C1=2.2pF(2.4GHz频段) | 接收灵敏度下降12dB,无法解调-85dBm信号 | 用网络分析仪测S11,要求<-10dB@2.4~2.4835GHz |
| AGC控制环路 | U3(OPA2350) | 反馈电阻Rf=47kΩ,采样电容Cagc=100nF | 增益调整延迟>8ms,导致突发信号失真 | 示波器测AGC_OUT引脚,阶跃响应上升时间应<3.5ms |
| 电源滤波 | C15/C16/C17 | 100nF+10μF+100μF三级并联 | 数字噪声耦合至ADC,SNR恶化8dB | 测VDDA引脚纹波,要求<2mVpp@1MHz |
注意:原理图中
JTAG/SWD调试接口必须保留,E题现场调试仅允许使用ST-Link V2。若原理图删除SWDIO/SWCLK引脚,需手工飞线——这是往届队伍高频失误点。
3. 固件核心逻辑逆向:FSK解调与AGC控制的代码级实现
3.1 FSK解调状态机设计与定时器配置
E题要求FSK中心频率915MHz,频偏±50kHz,波特率1200bps。解调采用过零检测法,关键代码位于src/fsk_demod.c:
// 使用TIM2作为基准时钟(1MHz),触发ADC采样 void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // ADC注入通道采集RF信号(PA0) ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T2_TRGO); ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE); } } // 注入转换完成中断处理 void ADC1_2_IRQHandler(void) { if (ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC) != RESET) { uint16_t adc_val = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1); static uint16_t last_val = 0; static uint8_t state = 0; // 0:low, 1:high // 过零检测:当前值>阈值且last_val<阈值 → 上升沿 if ((adc_val > 2048) && (last_val <= 2048)) { if (state == 0) { // 从低到高跳变 bit_counter++; if (bit_counter >= 8) { // 8个采样点判定一个符号 decode_fsm(bit_buffer); // 状态机解码 bit_counter = 0; } } state = 1; } else if ((adc_val <= 2048) && (last_val > 2048)) { state = 0; } last_val = adc_val; } }3.1.1 定时器TIM2参数计算依据
- 要求每比特采样8点 → 符号周期T=1/1200≈833.3μs → 单点间隔Δt=104.2μs
- TIM2时钟源为APB1=36MHz,预分频器PSC=35 → 计数器时钟=1MHz
- 自动重装载值ARR=104 → 溢出周期=104μs,误差仅0.2%
若实际测量符号同步失败,需用示波器抓取TIM2->CNT寄存器值,确认是否因中断优先级冲突导致计数器溢出丢失。
3.2 AGC环路控制算法实现与参数整定
AGC模块通过调节射频前端可变增益放大器(VGA)的控制电压,维持ADC输入信号峰峰值在2.0V±0.1V。核心逻辑在src/agc_control.c:
#define AGC_TARGET_PEAK 2048 // ADC满幅值4096的一半 #define AGC_STEP_SIZE 16 // 每次调整DAC步进值 void agc_update(void) { static uint16_t peak_val = 0; static uint16_t dac_val = 2048; // DAC初始值对应0V控制电压 // 获取当前ADC峰值(滑动窗口最大值) peak_val = get_peak_value(); // 从环形缓冲区读取最近128点最大值 if (peak_val > AGC_TARGET_PEAK + 100) { dac_val -= AGC_STEP_SIZE; // 信号过强,降低增益 } else if (peak_val < AGC_TARGET_PEAK - 100) { dac_val += AGC_STEP_SIZE; // 信号过弱,提高增益 } // 限幅:DAC输出范围0~4095 if (dac_val > 4095) dac_val = 4095; if (dac_val < 0) dac_val = 0; // 更新DAC输出(PA4引脚) DAC_SetChannel1Data(DAC_Align_12b_R, dac_val); }3.2.1 AGC动态响应优化技巧
原厂代码存在振荡问题,改进方案需引入滞后比较与积分限幅:
// 修改后的agc_update()关键段 static int16_t error_integral = 0; #define AGC_INTEGRAL_LIMIT 500 int16_t error = AGC_TARGET_PEAK - peak_val; error_integral += error; if (error_integral > AGC_INTEGRAL_LIMIT) error_integral = AGC_INTEGRAL_LIMIT; if (error_integral < -AGC_INTEGRAL_LIMIT) error_integral = -AGC_INTEGRAL_LIMIT; dac_val = 2048 + (error * 2) + (error_integral / 10); // P+I控制提示:
get_peak_value()函数若采用遍历环形缓冲区方式,会导致CPU占用率飙升。高效做法是维护一个单调递减队列(deque),插入新值时移除小于它的旧值,O(1)获取峰值——这是E题高分作品的共性优化。
4. 现场测试复现:用ST-Link V2烧录与信号发生器联调
4.1 ST-Link V2固件升级与连接稳定性保障
2020年现场大量队伍因ST-Link固件过旧导致烧录失败。必须将固件升级至V2.J37.M25(2020年7月发布):
# Windows下执行(需管理员权限) cd "C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility" ST-LINKUpgrade.exe -f "STLINK-V2.J37.M25.bin"升级后验证连接状态:
- LED指示灯:常亮绿灯(已连接),闪烁红灯(通信中)
- Keil中
Utilities → Settings → Debug → SW Device应显示STM32F103C8,而非Unknown device
若出现Cannot connect to target错误,90%原因是SWDIO/SWCLK引脚存在外部上拉电阻(>10kΩ)。E题板载设计要求这两根线悬空,需用万用表确认PCB上无额外电阻焊接。
4.2 信号发生器参数配置与误码率测试流程
使用Keysight N5171B或国产SG1000系列信号源模拟E题测试信号:
| 参数项 | 设置值 | 依据说明 |
|---|---|---|
| Frequency | 915.000 MHz | E题指定中心频点 |
| Modulation | FSK | 非GFSK,禁用高斯滤波 |
| Deviation | ±50 kHz | 频偏精度需≤±1kHz,否则解调失败 |
| Symbol Rate | 1200 Bd | 波特率误差>0.5%将导致帧同步丢失 |
| Output Power | -80 dBm | 对应接收灵敏度下限,需用衰减器校准 |
测试步骤:
- 将信号源RF OUT接至E题板RF IN,用5dB衰减器隔离;
- Keil中
Flash → Download烧录hex文件; - 按复位键,观察LED:绿色常亮表示AGC锁定,红色闪烁表示FSK解调中;
- 用逻辑分析仪抓取
USART1_TX(PB6)数据,导出CSV后用Python脚本计算误码率:
import numpy as np # 读取逻辑分析仪导出的UART数据(8N1格式) data = np.loadtxt('uart_capture.csv', delimiter=',', skiprows=1) # 提取有效数据帧(E题帧格式:0xAA + 8字节payload + 0x55) frames = [] for i in range(len(data)-10): if data[i]==0xAA and data[i+9]==0x55: frames.append(data[i+1:i+9]) # 计算误码率 errors = sum(np.sum(frame != expected_frame) for frame in frames) ber = errors / (len(frames)*8) print(f"BER = {ber:.2e}") # 要求≤1e-44.2.1 现场高频故障排查表
| 现象 | 可能原因 | 快速验证方法 |
|---|---|---|
| LED不亮 | BOOT0引脚未接地 | 用万用表测BOOT0对GND电压,应为0V |
| 接收无响应 | 射频前端未供电 | 测LNA芯片VCC引脚,应为3.3V |
| 解调数据乱码 | USART波特率不匹配 | 用示波器测TX引脚,计算周期是否为8.33μs(1200bps) |
| AGC电压恒定 | DAC通道未使能 | 查DAC_Cmd(DAC_Channel_1, ENABLE)是否被注释 |
5. 从竞赛资料到工程实践:三个可立即迁移的技术点
5.1 环形缓冲区的零拷贝DMA实现(适用于所有实时信号处理)
E题代码中src/ring_buffer.c实现了无内存复制的环形缓冲区,其DMA配置可直接复用于音频采集、电机编码器读取等场景:
// 初始化DMA传输(ADC注入通道→RAM) DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->JOFR1; // 注入偏移寄存器 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rx_buffer; // 用户缓冲区 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = RING_BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 关键:循环模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_Cmd(DMA1_Channel1, ENABLE);关键迁移点:
DMA_Mode_Circular使DMA在填满缓冲区后自动回到起点,配合DMA_GetCurrDataCounter()函数可实时获取已传输字节数,避免传统轮询方式消耗CPU资源。在STM32H7系列中,此模式支持双缓冲(Double Buffer Mode),进一步消除数据覆盖风险。
5.2 基于硬件定时器的微秒级延时函数(替代HAL_Delay)
E题要求FSK解调中符号间隔控制精度达0.1μs,而HAL_Delay()最小分辨率为1ms。自定义延时函数利用TIM5:
void delay_us(uint16_t us) { __HAL_TIM_SET_COUNTER(&htim5, 0); // 清零计数器 __HAL_TIM_SET_AUTORELOAD(&htim5, us); // 设置重装载值(TIM5时钟=1MHz) __HAL_TIM_ENABLE(&htim5); while (__HAL_TIM_GET_COUNTER(&htim5) < us); __HAL_TIM_DISABLE(&htim5); }5.2.1 定时器时钟源选择原则
| MCU系列 | 推荐定时器 | 时钟源配置 | 注意事项 |
|---|---|---|---|
| STM32F1 | TIM2/TIM5 | APB1=36MHz → PSC=35 → 1MHz | 避免使用TIM4(默认时钟源为APB1*2,易超频) |
| STM32F4 | TIM5 | APB1=42MHz → PSC=41 → 1MHz | TIM5为32位定时器,支持更大us范围 |
| STM32H7 | TIM2 | APB1=120MHz → PSC=119 → 1MHz | 需启用TIM2时钟使能(__HAL_RCC_TIM2_CLK_ENABLE()) |
5.3 电磁兼容性(EMC)设计自查清单(基于E题实测经验)
E题现场测试包含辐射发射(RE)和静电放电(ESD)两项,以下设计要点可直接用于工业产品:
| 检查项 | E题达标做法 | 工程迁移建议 |
|---|---|---|
| PCB分割 | 数字地与模拟地单点连接于ADC参考源旁 | 在混合信号PCB中,数字地平面挖空避开模拟走线,用0Ω电阻桥接 |
| 电源去耦 | 每个IC电源引脚配0.1μF陶瓷电容+10μF钽电容 | 高频芯片(如WiFi模组)需增加22pF高频去耦电容,位置距引脚<2mm |
| 时钟布线 | 24MHz晶振走线包地,长度<8mm | 所有高速时钟线(≥10MHz)必须包地,包地铜皮距走线边缘≥3倍线宽 |
| ESD防护 | USB接口TVS管(SMAJ5.0A)靠近连接器放置 | 任何外露接口(RS485、CAN)均需TVS+共模电感组合,TVS接地路径<5mm |
实测数据:某队伍在未做EMC优化时,辐射发射在240MHz频点超标12dB;按上述清单整改后,全频段低于Class B限值6dB。关键动作是将USB接口的TVS管从板边移到连接器焊盘正下方,接地过孔数量从1个增至4个。
本文还有配套的精品资源,点击获取