#include #include "esp32_s3_szp.h" #include "app_ui.h" #include #include #include "ecg_generator.h" #include "sine_generator.h" #include "esp_timer.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" EventGroupHandle_t my_event_group; // 按键定义 #define BUTTON_PIN GPIO_NUM_0 // 使用GPIO0作为按键输入 #define BUTTON_DEBOUNCE_MS 200 // 防抖时间 static const char *TAG = "MAIN"; // 信号生成器相关 static ecg_generator_t g_ecg_gen; static sine_generator_t g_sine_gen; static esp_timer_handle_t signal_timer = NULL; static uint32_t signal_sample_count = 0; static uint32_t signal_last_log_time = 0; static bool use_sine_wave = true; // true=正弦波, false=ECG // 信号生成器定时器回调函数 static void signal_timer_callback(void* arg) { float signal_voltage = 0.0f; if (use_sine_wave) { // 生成正弦波样本 signal_voltage = sine_generator_get_next_sample(&g_sine_gen); } else { // 生成ECG样本 signal_voltage = ecg_generator_get_next_sample(&g_ecg_gen); } // 输出到DAC通道2 set_channel_voltage(2, signal_voltage); signal_sample_count++; // 减少日志输出频率,避免影响高频中断性能 // 每20000个样本输出一次统计信息(约1秒) if (signal_sample_count >= 20000) { ESP_LOGI(TAG, "Generated %u samples at 20kHz (%s)", signal_sample_count, use_sine_wave ? "Sine Wave" : "ECG"); signal_sample_count = 0; signal_last_log_time = esp_timer_get_time() / 1000; } } // 函数声明 void displayMemoryUsage(void); void test_signal_generation(void); void switch_to_ecg_mode(void); void switch_to_sine_mode(void); // 信号生成器测试函数 void test_signal_generation(void) { ESP_LOGI(TAG, "=== Signal Generation Test ==="); // 初始化ECG生成器 ecg_generator_init(&g_ecg_gen, 20000.0f); // 20kHz生成率 ecg_param_set(&g_ecg_gen, 5.0f, 75.0f); // 初始化正弦波生成器 sine_generator_init(&g_sine_gen, 20000.0f); // 20kHz生成率 sine_generator_set_frequency(&g_sine_gen, 10.0f); // 100Hz正弦波 sine_generator_set_amplitude(&g_sine_gen, 5.0f); // 5mV // 创建定时器配置 const esp_timer_create_args_t timer_args = { .callback = &signal_timer_callback, .name = "signal_timer" }; // 创建定时器 esp_err_t ret = esp_timer_create(&timer_args, &signal_timer); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to create signal timer: %s", esp_err_to_name(ret)); return; } // 启动信号生成器 if (use_sine_wave) { sine_generator_start(&g_sine_gen); ESP_LOGI(TAG, "Started sine wave generator: 100Hz, 5mV"); } else { ecg_generator_start(&g_ecg_gen); ESP_LOGI(TAG, "Started ECG generator: 75 BPM, 5mV"); } // 启动定时器 (50us = 20kHz) ret = esp_timer_start_periodic(signal_timer, 50); // 50微秒 = 20kHz if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to start signal timer: %s", esp_err_to_name(ret)); esp_timer_delete(signal_timer); return; } ESP_LOGI(TAG, "Signal timer started at 20kHz (50us period)"); } // 切换到ECG模式 void switch_to_ecg_mode(void) { if (use_sine_wave) { sine_generator_stop(&g_sine_gen); ecg_generator_start(&g_ecg_gen); use_sine_wave = false; ESP_LOGI(TAG, "Switched to ECG mode"); } } // 切换到正弦波模式 void switch_to_sine_mode(void) { if (!use_sine_wave) { ecg_generator_stop(&g_ecg_gen); sine_generator_start(&g_sine_gen); use_sine_wave = true; ESP_LOGI(TAG, "Switched to sine wave mode"); } } // 按键初始化 void button_init(void) { gpio_config_t io_conf = {}; io_conf.intr_type = GPIO_INTR_DISABLE; io_conf.mode = GPIO_MODE_INPUT; io_conf.pin_bit_mask = (1ULL << BUTTON_PIN); io_conf.pull_down_en = 0; io_conf.pull_up_en = 1; // 启用上拉电阻 gpio_config(&io_conf); ESP_LOGI(TAG, "Button initialized on GPIO %d", BUTTON_PIN); } // 检测按键按下 bool button_pressed(void) { static uint32_t last_press_time = 0; uint32_t current_time = esp_timer_get_time() / 1000; // 转换为毫秒 // 检测按键按下(低电平) if (gpio_get_level(BUTTON_PIN) == 0) { // 防抖处理 if (current_time - last_press_time > BUTTON_DEBOUNCE_MS) { last_press_time = current_time; return true; } } return false; } // 打印内存使用情况 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初始化 button_init(); // 按键初始化 my_event_group = xEventGroupCreate(); ESP_LOGI(TAG, "Hardware initialization completed."); // 启动信号生成 test_signal_generation(); // LED状态指示 ESP_LOGI(TAG, "Starting LED status indicator..."); int led_count = 0; while (true) { // 检测按键按下 if (button_pressed()) { if (use_sine_wave) { switch_to_ecg_mode(); } else { switch_to_sine_mode(); } } // 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(); } } }