当前位置: 首页 > news >正文

[实战]调频三角波和锯齿波信号生成(完整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)

验证流程

  1. 编译运行C程序
gcc wave_generator.c -o wave_generator -lm
./wave_generator
  1. 生成文件
  • triangle.bin:三角波数据
  • sawtooth.bin:锯齿波数据
  1. 运行Python分析
python wave_analyzer.py
  1. 验证输出
  • 自动生成波形时域图

  • 频谱分析图
    锯齿波:
    在这里插入图片描述
    三角波:
    在这里插入图片描述

  • 关键参数验证报告:

      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]
    
  1. 分析图表
  • 时域波形(包含相位偏移和直流偏移效果)
  • 频谱图(验证基频和谐波分布)
  • 统计参数表(峰峰值、均值、标准差等)

此实现完整覆盖了信号生成、参数配置、数据存储和验证分析的全流程,可通过修改C程序中的WaveParams结构体或Python中的配置字典调整所有参数。


研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)


http://www.dtcms.com/a/274784.html

相关文章:

  • hbuilderx打包的应用上传苹果应用商店最简方法
  • 字节豆包又一个新功能,超级实用,4 种玩法,你肯定用得上!(建议收藏)
  • Uniapp视频聊天软件内容监控插件开发指南
  • OA系统中的搜索功能方案:简单搜索vs高级搜索
  • 2-Git提交本地项目到远程仓库
  • 问有几条病狗?
  • 【linux网络】深入理解 TCP/UDP:从基础端口号到可靠传输机制全解析
  • 机器学习-06(Optimization-自动调整学习率)
  • consul 的安装与服务发现
  • MOSS-TTSD V2版 - 文本到语音对话生成 支持零样本多人语音克隆 一键整合包下载
  • 一文速览DeepSeek-R1的本地部署——可联网、可实现本地知识库问答(附教程)
  • OBB旋转框检测配置与训练全流程(基于 DOTA8 数据集)
  • 第3章 操作臂运动学(笔记总结)
  • Hangfire 调用报错解决方案总结
  • 经典的垃圾收集器!!!
  • day02-数组part02
  • day67—DFS—被围绕的区域(LeetCode-130)
  • 飞算JavaAI 实战笔记
  • Qt中QGraphicsView类应用解析:构建高效2D图形界面的核心技术
  • 迭代器(c++)、智能指针
  • 【C/C++】动态内存分配:从 C++98 裸指针到现代策略
  • PyTorch武侠演义 第一卷:初入江湖 第1章:武林新秀遇Tensor - 张量基础
  • 技术突破与落地应用:端到端 2.0 时代辅助驾驶TOP10 论文深度拆解系列【第九篇(排名不分先后)】
  • 飞书CEO谢欣:挑战巨头,打造AI新时代的Office
  • Rail开发日志_6
  • Python类型注解中的`Optional`:深入理解难点解析(进阶版)
  • EndNote快速入手指南
  • CDN 加速与安全防护:双剑合璧的技术协同
  • manifest.json只有源码视图没其他配置
  • Tomcat问题:启动脚本startup.bat中文乱码问题解决