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

[实战]调频三角波和锯齿波信号生成(完整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.xdnf.cn/news/15130.html

相关文章:

  • 深入浅出:什么是MCP(模型上下文协议)?
  • 力扣网编程134题:加油站(双指针)
  • C++中柔性数组的现代化替代方案:从内存布局优化到标准演进
  • Debian:从GNOME切换到Xfce
  • 扫描文件 PDF / 图片 纠斜 | 图片去黑边 / 裁剪 / 压缩
  • I2C集成电路总线
  • Semi-Supervised Single-View 3D Reconstruction via Prototype Shape Priors
  • 基于Java Spring Boot开发的旅游景区智能管理系统 计算机毕业设计源码32487
  • linux网络编程之单reactor模型(一)
  • Python 数据建模与分析项目实战预备 Day 2 - 数据构建与字段解析(模拟简历结构化数据)
  • 【前端】【组件库开发】【原理】【无框架开发】现代网页弹窗开发指南:从基础到优化
  • GNhao,获取跨境手机SIM卡跨境通信新选择!
  • 手机恢复出厂设置怎么找回数据?Aiseesoft FoneLab for Android数据恢复工具分享
  • Java中的泛型继承
  • 深度学习篇---昇腾NPUCANN 工具包
  • 《Java EE与中间件》实验三 基于Spring Boot框架的购物车
  • BLOB 数据的插入与读取详解
  • Linux驱动学习day22(interrupt子系统)
  • [python]在drf中使用drf_spectacular
  • 卢比危机下的金融破局:科伦坡交易所技术升级作战图
  • SpringBoot JWT
  • NFS文件存储及论坛项目搭建(php)
  • Web攻防-SSTI服务端模版注入利用分类语言引擎数据渲染项目工具挖掘思路
  • MCU芯片内部的ECC安全机制
  • OpenCV图像基本操作:读取、显示与保存
  • 《数据库》MySQL备份回复
  • AI加持的开源知识库新秀:PandaWiki,如何用它打造智能化文档系统?
  • 新作品:吃啥好呢 - 个性化美食推荐
  • [面试] 手写题-爬楼梯,斐波那契数列
  • 利用Claude code,只用文字版系统设计大纲,就能轻松实现系统~