#include #include "esp32_s3_szp.h" #include "app_ui.h" #include #include #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(); } } }