Stimulate/components/signal_generators/src/sine_generator.c

200 lines
6.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "sine_generator.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "esp_log.h"
// 初始化正弦波生成器
void sine_generator_init(sine_generator_t *generator, float sample_rate) {
if (generator == NULL) return;
memset(generator, 0, sizeof(sine_generator_t));
// 设置默认参数
generator->frequency = 200.0f; // 默认200Hz正弦波
generator->amplitude = 1.0f; // 幅值1.0V
generator->sample_rate = sample_rate;
generator->is_running = false;
// 查找表参数
generator->sine_lookup_table = NULL;
generator->table_size = 0;
generator->table_index = 0;
}
// 设置正弦波频率
void sine_generator_set_frequency(sine_generator_t *generator, float frequency) {
if (generator == NULL) return;
// 限制频率范围
if (frequency < 0.1f) frequency = 0.1f;
if (frequency > 10000.0f) frequency = 10000.0f;
generator->frequency = frequency;
// 如果已经运行,重新生成查找表
if (generator->is_running) {
sine_generator_generate_lookup_table(generator);
}
ESP_LOGI("SINE_GEN", "Sine wave frequency set to: %.1f Hz", frequency);
}
// 设置幅值直接输入mV值内部自动转换为DAC输出值
void sine_generator_set_amplitude(sine_generator_t *generator, float amplitude_mv) {
if (generator == NULL) return;
// 硬件衰减系数约38倍 (根据实际测量0.132V → 5mV)
// 对应关系amplitude(V) × 38 ≈ 示波器显示值(mV)
const float attenuation_factor = 38.0f;
// 将mV除以衰减系数得到DAC输出值
float dac_amplitude = amplitude_mv / attenuation_factor;
generator->amplitude = dac_amplitude;
// 如果已经运行,重新生成查找表
if (generator->is_running) {
sine_generator_generate_lookup_table(generator);
}
ESP_LOGI("SINE_GEN", "Sine wave amplitude set to: %.1f mV", amplitude_mv);
}
// 开始生成
void sine_generator_start(sine_generator_t *generator) {
if (generator == NULL) return;
generator->is_running = true;
generator->sample_count = 0;
// 生成查找表
sine_generator_generate_lookup_table(generator);
ESP_LOGI("SINE_GEN", "Sine generator started: %.1f Hz, %.1f mV",
generator->frequency, generator->amplitude * 38.0f);
}
// 停止生成
void sine_generator_stop(sine_generator_t *generator) {
if (generator == NULL) return;
generator->is_running = false;
ESP_LOGI("SINE_GEN", "Sine generator stopped");
}
// 重置生成器
void sine_generator_reset(sine_generator_t *generator) {
if (generator == NULL) return;
generator->sample_count = 0;
generator->table_index = 0;
}
// 获取下一个样本
float sine_generator_get_next_sample(sine_generator_t *generator) {
if (generator == NULL || !generator->is_running) {
return 0.0f;
}
// 使用预计算的查找表,超高速访问
if (generator->sine_lookup_table != NULL && generator->table_size > 0) {
// 从查找表获取预计算的值
float sine_value = generator->sine_lookup_table[generator->table_index];
// 更新索引,循环使用查找表
generator->table_index = (generator->table_index + 1) % generator->table_size;
generator->sample_count++;
return sine_value;
} else {
// 如果查找表未初始化,使用实时计算(备用方案)
float t = (float)generator->sample_count / generator->sample_rate;
float sine_value = generator->amplitude * sinf(2.0f * M_PI * generator->frequency * t);
// 添加偏置电压
float offset = generator->amplitude;
sine_value = sine_value + offset;
// 限制在DAC有效范围内
if (sine_value < 0.0f) sine_value = 0.0f;
if (sine_value > 2.048f) sine_value = 2.048f;
generator->sample_count++;
return sine_value;
}
}
// 生成正弦波查找表
void sine_generator_generate_lookup_table(sine_generator_t *generator) {
if (generator == NULL) return;
// 释放旧的查找表
sine_generator_free_lookup_table(generator);
// 计算查找表大小:一个完整周期的样本数
// 表大小 = 采样率 / 正弦波频率
generator->table_size = (uint32_t)(generator->sample_rate / generator->frequency);
// 确保表大小至少为1
if (generator->table_size < 1) {
generator->table_size = 1;
}
// 分配内存
generator->sine_lookup_table = (float*)malloc(generator->table_size * sizeof(float));
if (generator->sine_lookup_table == NULL) {
ESP_LOGE("SINE_GEN", "Failed to allocate memory for sine lookup table");
generator->table_size = 0;
return;
}
// 预计算正弦波值
for (uint32_t i = 0; i < generator->table_size; i++) {
// 计算时间点
float t = (float)i / generator->sample_rate;
// 计算正弦波值
float sine_value = generator->amplitude * sinf(2.0f * M_PI * generator->frequency * t);
// 添加偏置电压
float offset = generator->amplitude;
sine_value = sine_value + offset;
// 限制在DAC有效范围内
if (sine_value < 0.0f) sine_value = 0.0f;
if (sine_value > 2.048f) sine_value = 2.048f;
generator->sine_lookup_table[i] = sine_value;
}
// 重置索引
generator->table_index = 0;
ESP_LOGI("SINE_GEN", "Generated sine lookup table: %u points, %.1f Hz",
generator->table_size, generator->frequency);
}
// 释放正弦波查找表
void sine_generator_free_lookup_table(sine_generator_t *generator) {
if (generator == NULL) return;
if (generator->sine_lookup_table != NULL) {
free(generator->sine_lookup_table);
generator->sine_lookup_table = NULL;
}
generator->table_size = 0;
generator->table_index = 0;
}
// 清理生成器(释放所有资源)
void sine_generator_cleanup(sine_generator_t *generator) {
if (generator == NULL) return;
generator->is_running = false;
sine_generator_free_lookup_table(generator);
ESP_LOGI("SINE_GEN", "Sine generator cleaned up");
}