Stimulate/main/main.c

150 lines
4.8 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 <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();
}
}
}