调频Chrip信号生成
不依赖任何第三方库,用C语言生成Chrip信号,并使用python进行数据频谱分析,确认C语言实现的正确性。
话不多说,实战开始。
调频Chirp信号原理
调频Chirp信号是一种频率随时间线性变化的信号,其数学表达式为:
s(t) = A * cos(2π * (f₀t + (k/2)t²) + φ)
其中:
A
:信号幅度f₀
:起始频率k
:调频率(频率变化速率)φ
:初始相位t
:时间
瞬时频率为:f(t) = f₀ + k*t
常见可配置参数
- 采样率:每秒采样点数 (Hz)
- 起始频率:Chirp的初始频率 (Hz)
- 结束频率:Chirp的终止频率 (Hz)
- 持续时间:信号长度 (秒)
- 幅度:信号峰值幅度
- 初始相位:信号的初始相位 (弧度)
- 方向:频率增加(UP)/减少(DOWN)
C语言实现:生成Chirp信号并保存为BIN文件
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
typedef struct {
double sample_rate; // 采样率 (Hz)
double start_freq; // 起始频率 (Hz)
double end_freq; // 结束频率 (Hz)
double duration; // 持续时间 (秒)
double amplitude; // 幅度
double init_phase; // 初始相位 (弧度)
int direction; // 方向: 0=UP, 1=DOWN
} ChirpConfig;
void generate_chirp(ChirpConfig config, const char* filename) {
// 计算总采样点数
int total_samples = (int)(config.duration * config.sample_rate);
float* buffer = (float*)malloc(total_samples * sizeof(float));
// 计算调频率 k (Hz/s)
double k = (config.end_freq - config.start_freq) / config.duration;
if (config.direction == 1) { // DOWN chirp
k = -k;
double temp = config.start_freq;
config.start_freq = config.end_freq;
config.end_freq = temp;
}
// 生成Chirp信号
for (int i = 0; i < total_samples; i++) {
double t = i / config.sample_rate;
double phase = 2 * M_PI * (config.start_freq * t + 0.5 * k * t * t) + config.init_phase;
buffer[i] = (float)(config.amplitude * cos(phase));
}
// 保存为二进制文件
FILE* file = fopen(filename, "wb");
fwrite(buffer, sizeof(float), total_samples, file);
fclose(file);
free(buffer);
}
int main() {
// 配置参数示例
ChirpConfig config = {
.sample_rate = 48000.0, // 48 kHz采样率
.start_freq = 100.0, // 100 Hz起始
.end_freq = 10000.0, // 10 kHz结束
.duration = 2.0, // 2秒时长
.amplitude = 0.8, // 80%幅度
.init_phase = 0.0, // 零相位
.direction = 0 // UP chirp
};
generate_chirp(config, "chirp_signal.bin");
printf("Chirp信号已生成并保存到 chirp_signal.bin\n");
return 0;
}
编译运行:
gcc chirp_generator.c -lm -o chirp_generator
./chirp_generator
Python验证:读取BIN文件并分析
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import spectrogram
# 读取二进制文件
def read_chirp_bin(filename):
with open(filename, 'rb') as f:
data = np.fromfile(f, dtype=np.float32)
return data
# 分析Chirp信号
def analyze_chirp(data, sample_rate, config):
# 创建时间轴
duration = len(data) / sample_rate
time = np.linspace(0, duration, len(data))
# 绘制时域波形
plt.figure(figsize=(12, 8))
plt.subplot(3, 1, 1)
plt.plot(time, data)
plt.title('Chirp Signal - Time Domain')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.grid(True)
plt.xlim(0, min(0.1, duration)) # 显示前100ms细节
# 计算并绘制频谱
plt.subplot(3, 1, 2)
fft_result = np.fft.rfft(data)
freqs = np.fft.rfftfreq(len(data), 1/sample_rate)
plt.plot(freqs, np.abs(fft_result))
plt.title('Frequency Spectrum')
plt.xlabel('Frequency (Hz)')
plt.ylabel('Magnitude')
plt.grid(True)
plt.xlim(config['start_freq']-500, config['end_freq']+500)
# 计算并绘制时频谱
plt.subplot(3, 1, 3)
f, t, Sxx = spectrogram(data, fs=sample_rate, nperseg=1024)
plt.pcolormesh(t, f, 10 * np.log10(Sxx), shading='gouraud')
plt.title('Spectrogram')
plt.ylabel('Frequency (Hz)')
plt.xlabel('Time (s)')
plt.ylim(0, 1.2 * max(config['start_freq'], config['end_freq']))
plt.colorbar(label='Intensity (dB)')
plt.tight_layout()
plt.savefig('chirp_analysis.png')
plt.show()
# 打印关键指标
expected_k = (config['end_freq'] - config['start_freq']) / config['duration']
print(f"验证结果:")
print(f"- 采样点数: {len(data)}")
print(f"- 持续时间: {duration:.2f}s (预期: {config['duration']}s)")
print(f"- 频率范围: {freqs[np.argmax(fft_result)]:.0f}Hz (起始预期: {config['start_freq']}Hz)")
print(f"- 调频斜率: {expected_k:.0f} Hz/s")
# 配置参数(需与C程序一致)
config = {
'sample_rate': 48000,
'start_freq': 100,
'end_freq': 10000,
'duration': 2.0,
'amplitude': 0.8,
'direction': 'UP'
}
# 读取并分析数据
data = read_chirp_bin("chirp_signal.bin")
analyze_chirp(data, config['sample_rate'], config)
验证结果分析
-
时域图:
- 显示信号波形随时间变化
- 初期波形稀疏(低频),后期密集(高频)
-
频谱图:
- 显示信号在100Hz-10kHz范围有显著能量
- 峰值位置与起始频率一致
-
时频谱:
- 清晰展示频率随时间线性变化
- 斜率为 (10000-100)/2 = 4950 Hz/s
- 验证UP/DOWN方向正确性
-
控制台输出:
- 报告实际持续时间、频率范围等参数
- 与输入参数对比验证一致性
验证结果: - 采样点数: 96000 - 持续时间: 2.00s (预期: 2.0s) - 频率范围: 5430Hz (起始预期: 100Hz) - 调频斜率: 4950 Hz/s
验证要点
- 频率范围:起始/结束频率应与配置一致
- 持续时间:信号长度应匹配设定时长
- 调频方向:时频谱斜率方向应与配置一致
- 线性度:时频谱应呈直线特征
- 幅度:时域峰值应与设定幅度匹配
此方案完整实现了Chirp信号的生成、存储和验证流程,所有关键参数均可配置,并通过可视化分析确保信号生成正确性。
研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)