[实战]调频三角波和锯齿波信号生成(完整C代码)
调频三角波和锯齿波信号生成
文章目录
- 调频三角波和锯齿波信号生成
- 调频三角波和锯齿波信号原理
- 三角波信号
- 锯齿波信号
- 常见可配置参数
- C语言实现 (wave_generator.c)
- Python验证脚本 (wave_analyzer.py)
- 验证流程
不依赖任何第三方库,用C语言生成调频三角波以及锯齿波信号,并使用python进行数据频谱分析,确认C语言实现的正确性。
话不多说,实战开始。
调频三角波和锯齿波信号原理
三角波信号
- 原理:由线性上升段和线性下降段组成,形成三角形周期波形
- 数学表达式:
( x(t) = \begin{cases}
\frac{2A}{T}(t - nT) & \text{上升段} \
A - \frac{2A}{T}(t - nT - \frac{T}{2}) & \text{下降段}
\end{cases} ) - 特点:奇次谐波含量丰富,谐波幅度以 ( 1/n^2 ) 衰减
锯齿波信号
- 原理:线性上升后瞬时复位(正向锯齿波)或线性下降后瞬时复位(反向锯齿波)
- 数学表达式:
( x(t) = 2A \left( \frac{t}{T} - \text{floor}\left(\frac{t}{T} + \frac{1}{2}\right) \right) ) - 特点:包含所有整数次谐波,幅度以 ( 1/n ) 衰减
常见可配置参数
参数 | 描述 | 典型值 |
---|---|---|
振幅 | 信号峰值幅度 | 0.1-5.0 |
频率 | 基础频率(Hz) | 1-10000 |
采样率 | 采样点数/秒 | 44100 |
时长 | 信号持续时间(s) | 0.1-10 |
波形类型 | 0=三角波, 1=锯齿波 | 0/1 |
相位偏移 | 波形起始相位(度) | 0-360 |
直流偏移 | 信号垂直偏移量 | -1.0-1.0 |
对称度 | 三角波上升/下降比 | 0.1-0.9 |
方向 | 锯齿波方向(0=下降,1=上升) | 0/1 |
C语言实现 (wave_generator.c)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>typedef struct {float amplitude; // 振幅float frequency; // 频率 (Hz)float sample_rate; // 采样率 (Hz)float duration; // 时长 (秒)int wave_type; // 0=三角波, 1=锯齿波float phase_offset; // 相位偏移 (度)float dc_offset; // 直流偏移float symmetry; // 三角波对称度 (0.1-0.9)int direction; // 锯齿波方向 (0=下降,1=上升)
} WaveParams;void generate_waveform(const char* filename, WaveParams params) {// 计算总采样点数int total_samples = (int)(params.duration * params.sample_rate);float* buffer = (float*)malloc(total_samples * sizeof(float));// 相位偏移转换 (度 -> 弧度)float phase_rad = params.phase_offset * M_PI / 180.0f;for (int i = 0; i < total_samples; i++) {float t = i / params.sample_rate;float phase = 2 * M_PI * params.frequency * t + phase_rad;float value;if (params.wave_type == 0) { // 三角波float mod_phase = fmod(phase, 2 * M_PI) / (2 * M_PI);if (mod_phase < params.symmetry) {value = 2 * mod_phase / params.symmetry - 1;} else {value = 1 - 2 * (mod_phase - params.symmetry) / (1 - params.symmetry);}} else { // 锯齿波value = 2 * fmod(phase / (2 * M_PI), 1.0f) - 1;if (!params.direction) value = -value; // 方向控制}buffer[i] = params.amplitude * value + params.dc_offset;}// 写入二进制文件FILE* file = fopen(filename, "wb");fwrite(buffer, sizeof(float), total_samples, file);fclose(file);free(buffer);
}int main() {WaveParams params = {.amplitude = 1.0f, // 振幅1.0.frequency = 5.0f, // 5Hz.sample_rate = 44100, // 44.1kHz采样率.duration = 2.0f, // 2秒时长.wave_type = 0, // 三角波.phase_offset = 30.0f, // 30度相位偏移.dc_offset = 0.1f, // 0.1直流偏移.symmetry = 0.3f, // 30%上升/70%下降.direction = 1 // 锯齿波方向(三角波无效)};generate_waveform("triangle.bin", params);// 生成锯齿波示例params.wave_type = 1;params.direction = 0;generate_waveform("sawtooth.bin", params);return 0;
}
Python验证脚本 (wave_analyzer.py)
import numpy as np
import matplotlib.pyplot as plt
from scipy import signaldef analyze_waveform(filename, params):# 读取二进制文件with open(filename, 'rb') as f:data = np.fromfile(f, dtype=np.float32)# 创建时间轴t = np.arange(len(data)) / params['sample_rate']# 绘制波形plt.figure(figsize=(12, 8))# 时域图plt.subplot(3, 1, 1)plt.plot(t, data)plt.title(f"{'Triangle' if params['wave_type'] == 0 else 'Sawtooth'} Waveform")plt.xlabel('Time (s)')plt.ylabel('Amplitude')plt.grid(True)# FFT频谱分析plt.subplot(3, 1, 2)n = len(data)freq = np.fft.rfftfreq(n, d=1/params['sample_rate'])fft_vals = np.abs(np.fft.rfft(data)) / nplt.plot(freq, fft_vals)plt.xlim(0, 10 * params['frequency'])plt.title('Frequency Spectrum')plt.xlabel('Frequency (Hz)')plt.ylabel('Magnitude')plt.grid(True)# 统计验证plt.subplot(3, 1, 3)stats = {'Max': np.max(data),'Min': np.min(data),'Mean': np.mean(data),'Std': np.std(data),'Duration': params['duration'],'Samples': len(data)}# 添加统计文本text = "\n".join([f"{k}: {v:.4f}" for k, v in stats.items()])plt.text(0.5, 0.5, text, ha='center', va='center', fontsize=12)plt.axis('off')plt.tight_layout()plt.savefig(f"{filename[:-4]}_analysis.png")plt.show()# 返回关键指标return {'peak_to_peak': stats['Max'] - stats['Min'],'dc_offset': stats['Mean'],'fundamental_freq': freq[np.argmax(fft_vals[1:]) + 1]}# 配置参数(需与C程序匹配)
triangle_params = {'amplitude': 1.0,'frequency': 5.0,'sample_rate': 44100,'duration': 2.0,'wave_type': 0,'phase_offset': 30.0,'dc_offset': 0.1,'symmetry': 0.3
}sawtooth_params = {'amplitude': 1.0,'frequency': 5.0,'sample_rate': 44100,'duration': 2.0,'wave_type': 1,'phase_offset': 30.0,'dc_offset': 0.1,'direction': 0
}# 分析波形
print("Triangle Wave Analysis:")
triangle_results = analyze_waveform("triangle.bin", triangle_params)print("\nSawtooth Wave Analysis:")
sawtooth_results = analyze_waveform("sawtooth.bin", sawtooth_params)# 验证关键参数
def verify_parameters(expected, measured, tolerance=0.05):for param, value in expected.items():measured_val = measured.get(param.lower(), None)if measured_val is not None:error = abs(measured_val - value) / valuestatus = "PASS" if error < tolerance else "FAIL"print(f"{param}: Expected={value:.4f}, Measured={measured_val:.4f}, Error={error*100:.2f}% [{status}]")print("\nTriangle Wave Verification:")
verify_parameters({'Amplitude': triangle_params['amplitude'],'DC_Offset': triangle_params['dc_offset'],'Frequency': triangle_params['frequency']
}, {'amplitude': triangle_results['peak_to_peak'] / 2,'dc_offset': triangle_results['dc_offset'],'frequency': triangle_results['fundamental_freq']
})print("\nSawtooth Wave Verification:")
verify_parameters({'Amplitude': sawtooth_params['amplitude'],'DC_Offset': sawtooth_params['dc_offset'],'Frequency': sawtooth_params['frequency']
}, sawtooth_results)
验证流程
- 编译运行C程序:
gcc wave_generator.c -o wave_generator -lm
./wave_generator
- 生成文件:
triangle.bin
:三角波数据sawtooth.bin
:锯齿波数据
- 运行Python分析:
python wave_analyzer.py
- 验证输出:
-
自动生成波形时域图
-
频谱分析图
锯齿波:
三角波:
-
关键参数验证报告:
Triangle Wave Verification:Amplitude: Expected=1.0000, Measured=1.0000, Error=0.00% [PASS]DC_Offset: Expected=0.1000, Measured=0.1000, Error=0.00% [PASS]Frequency: Expected=5.0000, Measured=5.0000, Error=0.00% [PASS]Sawtooth Wave Verification:DC_Offset: Expected=0.1000, Measured=0.1000, Error=0.05% [PASS]
- 分析图表:
- 时域波形(包含相位偏移和直流偏移效果)
- 频谱图(验证基频和谐波分布)
- 统计参数表(峰峰值、均值、标准差等)
此实现完整覆盖了信号生成、参数配置、数据存储和验证分析的全流程,可通过修改C程序中的WaveParams结构体或Python中的配置字典调整所有参数。
研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)