前言
本次方案除增益为 1 的加法器部分外,核心处理逻辑均由 FPGA 配合 STM32 完成。主要目标是输入混合信号 C,从中解调出原始的两路波形 A'和 B'。
题目背景
题目要求从信号发生器输出两路波形 A 和 B,通过加法器生成信号 C。我们需要做的就是从 C 中将 A'和 B'解出来。常见的思路是对 C 进行傅里叶变换识别成分后分离,但考虑到重构波形与原信号时钟不同步会导致相位漂移,本方案采用了锁相环技术来锁定相位。
系统架构
数据流向如下: C 信号 → 高速 ADC → FPGA → FIFO → 串口 → STM32 → FFT 分析 → 识别波形/频率 → 串口 → DDS 重构 → 锁相环 → 高速 DAC → A',B'
核心模块实现
1. 数据采集与传输(FPGA)
这部分主要解决跨时钟域问题。ADC 采样率为 1MHz,而串口发送速率仅为 12.5KHz,中间必须使用 FIFO 缓冲。
FIFO 控制逻辑 写入侧跟随 ADC 时钟(1MHz),读取侧跟随串口波特率分频后的时钟。状态机控制读写使能,防止溢出或下溢。
assign ad9238_clk_ch0 = clk_1M;
wire wr_en, rd_en, full, empty;
reg [7:0] w_data;
localparam W_IDLE = 1, W_FIFO = 2;
reg[2:0] write_state, next_write_state;
always@(posedge clk_1M or negedge rst) begin
if(rst == 1'b0) write_state <= W_IDLE;
else write_state <= next_write_state;
end
always@(*) begin
case(write_state)
W_IDLE: if(empty == 1'b1) next_write_state <= W_FIFO; else next_write_state <= W_IDLE;
W_FIFO: if(full == 1'b1) next_write_state <= W_IDLE; else next_write_state <= W_FIFO;
default: next_write_state <= W_IDLE;
endcase
end
assign wr_en = (next_write_state == W_FIFO) ? 1'b1 : 1'b0;
// ... 后续 FIFO 实例化代码 ...
串口通信
FPGA 端负责将采集到的数据打包发送,并接收 STM32 返回的分析结果。帧头设为 0xFF,帧尾 0xFE,中间包含波形类型和频率信息。
注意:实际工程中 tx_vilid 拼写有误,应修正为 tx_valid,这里保留原意但建议统一命名规范。
2. 信号分析与识别(STM32)
STM32 通过串口中断接收数据,利用 DSP 库进行 FFT 运算。由于题目不要求峰峰值完全一致,我们主要关注频谱特征。
FFT 处理流程
- 确定频率范围 20KHz-100KHz,步进 5KHz。
- 计算各频段能量,找出能量最大的两个点作为主波频率。
- 根据基波幅值判断波形:正弦波单音集中,三角波含三次谐波导致基波削弱。设定阈值区分正弦波与三角波。
// FFT 能量聚集与峰值查找
for (int i=35; i<1000; i++) {
freq = (int)(((float)i*1000000/2048/5000)+0.5);
if(freq==freq_last) {
v_max = FFT_output[i]*FFT_output[i]+v_max;
} {
v_max = (v_max);
freq_change[cnt] = v_max;
fre[cnt] = freq;
freq_last=freq;
cnt++;
}
}
( i=; i<; i++) {
(freq_change[i]>max[]) { }
(freq_change[i]>max[] && freq_change[i]<max[]) { }
}
(max[]>) wave[] = ;
wave[] = ;


