Stimulate/main/main.c

150 lines
4.8 KiB
C
Raw Normal View History

2025-09-25 18:50:48 +08:00
#include <stdio.h>
#include "esp32_s3_szp.h"
#include "app_ui.h"
#include <esp_system.h>
#include <math.h>
#include "ecg_generator.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
EventGroupHandle_t my_event_group;
static const char *TAG = "MAIN";
// ECG定时器相关
static ecg_generator_t g_ecg_gen;
static esp_timer_handle_t ecg_timer = NULL;
static uint32_t ecg_sample_count = 0;
static uint32_t ecg_last_log_time = 0;
// ECG定时器回调函数
static void ecg_timer_callback(void* arg) {
// 生成ECG样本
float ecg_voltage = ecg_generator_get_next_sample(&g_ecg_gen);
// 输出到DAC通道2
set_channel_voltage(2, ecg_voltage);
ecg_sample_count++;
// 每秒输出一次统计信息
uint32_t now = esp_timer_get_time() / 1000; // 转换为毫秒
if (now - ecg_last_log_time >= 1000) {
ESP_LOGI(TAG, "ECG Timer: %u samples in 1s (%.1f Hz)",
ecg_sample_count, (float)ecg_sample_count);
ecg_sample_count = 0;
ecg_last_log_time = now;
}
}
// 函数声明
void displayMemoryUsage(void);
void test_ecg_generation(void);
// ECG测试函数
void test_ecg_generation(void) {
ESP_LOGI(TAG, "=== ECG Generation Test ===");
// 初始化ECG生成器
ecg_generator_init(&g_ecg_gen, 250.0f); // 250Hz采样率
// 设置ECG参数
ecg_generator_set_heart_rate(&g_ecg_gen, 75.0f); // 75次/分
ecg_generator_set_amplitude(&g_ecg_gen, 5.0f); // 直接设置5mV幅值内部自动转换
// 幅值设置说明:
// ecg_generator_set_amplitude() 现在直接接受mV值
// 内部自动处理硬件衰减系数转换
// 例如set_amplitude(5.0f) → 示波器显示5mV
ESP_LOGI(TAG, "ECG Parameters:");
ESP_LOGI(TAG, " Heart Rate: %.1f BPM", g_ecg_gen.heart_rate);
ESP_LOGI(TAG, " Amplitude: %.1f V", g_ecg_gen.amplitude);
ESP_LOGI(TAG, " Sample Rate: %.1f Hz", g_ecg_gen.sample_rate);
// 创建定时器配置
const esp_timer_create_args_t timer_args = {
.callback = &ecg_timer_callback,
.name = "ecg_timer"
};
// 创建定时器
esp_err_t ret = esp_timer_create(&timer_args, &ecg_timer);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to create ECG timer: %s", esp_err_to_name(ret));
return;
}
// 启动ECG生成器
ecg_generator_start(&g_ecg_gen);
// 启动定时器 (4ms = 250Hz)
ret = esp_timer_start_periodic(ecg_timer, 4000); // 4000微秒 = 4ms
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to start ECG timer: %s", esp_err_to_name(ret));
esp_timer_delete(ecg_timer);
return;
}
ESP_LOGI(TAG, "ECG timer started at 250Hz (4ms period)");
ESP_LOGI(TAG, "ECG generation is now running...");
}
// 打印内存使用情况
void displayMemoryUsage() {
size_t totalDRAM = heap_caps_get_total_size(MALLOC_CAP_INTERNAL);
size_t freeDRAM = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
size_t usedDRAM = totalDRAM - freeDRAM;
size_t totalPSRAM = heap_caps_get_total_size(MALLOC_CAP_SPIRAM);
size_t freePSRAM = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
size_t usedPSRAM = totalPSRAM - freePSRAM;
size_t DRAM_largest_block = heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL);
size_t PSRAM_largest_block = heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM);
float dramUsagePercentage = (float)usedDRAM / totalDRAM * 100;
float psramUsagePercentage = (float)usedPSRAM / totalPSRAM * 100;
ESP_LOGI(TAG, "DRAM Total: %zu bytes, Used: %zu bytes, Free: %zu bytes, DRAM_Largest_block: %zu bytes", totalDRAM, usedDRAM, freeDRAM, DRAM_largest_block);
ESP_LOGI(TAG, "DRAM Used: %.2f%%", dramUsagePercentage);
ESP_LOGI(TAG, "PSRAM Total: %zu bytes, Used: %zu bytes, Free: %zu bytes, PSRAM_Largest_block: %zu bytes", totalPSRAM, usedPSRAM, freePSRAM, PSRAM_largest_block);
ESP_LOGI(TAG, "PSRAM Used: %.2f%%", psramUsagePercentage);
}
// 主函数
void app_main(void)
{
ESP_LOGI(TAG, "Starting ECG application...");
// 硬件初始化
bsp_i2c_init(); // I2C初始化
LED_init(); // LED初始化
init_ad5328(); // DAC初始化
my_event_group = xEventGroupCreate();
ESP_LOGI(TAG, "Hardware initialization completed.");
// 启动ECG生成
test_ecg_generation();
// LED状态指示
ESP_LOGI(TAG, "Starting LED status indicator...");
int led_count = 0;
while (true) {
// LED闪烁指示系统运行
gpio_set_level(LED_PIN, 1); // LED亮
vTaskDelay(pdMS_TO_TICKS(1000));
gpio_set_level(LED_PIN, 0); // LED灭
vTaskDelay(pdMS_TO_TICKS(1000));
// 每10次循环显示一次内存使用情况
if (++led_count % 10 == 0) {
displayMemoryUsage();
}
}
}