Electricity/缓进缓出功能说明_修正版.md

5.8 KiB
Raw Blame History

缓进缓出功能说明(修正版)

问题分析

原始实现存在定时器冲突问题:

  • 2ms定时器与1s定时器产生冲突
  • 缓进缓出处理在2ms中断中执行干扰了主循环的电刺激处理
  • 导致在示波器上观察不到有效波形

解决方案

采用方波周期计数的方式实现缓进缓出,避免定时器冲突:

1. 计算原理

根据您的分析:

  • 每个方波周期100微秒
  • 2秒内方波周期数2,000,000 ÷ 100 = 20,000个
  • 强度从0增加到128需要128个步进
  • 每个步进的方波周期数20,000 ÷ 128 ≈ 156.25个

2. 实现方式

// 计算每个强度步进需要的方波周期数
uint32_t waves_per_step = (g_ems_config.ramp_up_time * 20000) / g_ems_config.intensity;
// 例如2秒 × 20000 ÷ 128 = 156.25个方波周期

核心变量

// 缓进缓出控制变量
static volatile uint16_t g_current_intensity = 0;  // 当前强度
static volatile uint8_t g_ramp_phase = 0;          // 渐进阶段0=缓进, 1=保持, 2=缓出
static volatile uint32_t g_wave_counter = 0;       // 方波周期计数器
static volatile uint32_t g_ramp_step_counter = 0;  // 缓进步进计数器

工作流程

1. 缓进阶段0-2秒

case 0:  // 缓进阶段
    if (g_ramp_step_counter < g_ems_config.ramp_up_time) {
        // 每156个方波周期增加1个强度单位
        if (g_wave_counter >= waves_per_step) {
            g_wave_counter = 0;  // 重置方波计数器
            if (g_current_intensity < g_ems_config.intensity) {
                g_current_intensity++;
            }
        }
        g_ramp_step_counter++;
    } else {
        // 缓进完成,进入保持阶段
        g_ramp_phase = 1;
        g_ramp_step_counter = 0;
        g_current_intensity = g_ems_config.intensity;
    }
    break;

2. 保持阶段2-8秒

case 1:  // 保持阶段
    if (g_ramp_step_counter < g_ems_config.hold_time) {
        // 保持最大强度
        g_current_intensity = g_ems_config.intensity;
        g_ramp_step_counter++;
    } else {
        // 保持完成,进入缓出阶段
        g_ramp_phase = 2;
        g_ramp_step_counter = 0;
        g_wave_counter = 0;
    }
    break;

3. 缓出阶段8-10秒

case 2:  // 缓出阶段
    if (g_ramp_step_counter < g_ems_config.ramp_down_time) {
        // 每156个方波周期减少1个强度单位
        if (g_wave_counter >= waves_per_step) {
            g_wave_counter = 0;  // 重置方波计数器
            if (g_current_intensity > 0) {
                g_current_intensity--;
            }
        }
        g_ramp_step_counter++;
    } else {
        // 缓出完成,停止电刺激
        g_current_intensity = 0;
    }
    break;

调用方式

缓进缓出处理函数在电刺激处理函数中调用:

void EMS_Process(void)
{
    if(g_ems_running) {
        g_ems_count++;
        
        // 处理缓进缓出控制
        EMS_Process_Ramp();
        
        // 使用当前缓进缓出的强度
        uint16_t current_intensity = g_current_intensity;
        
        // 生成方波信号
        wavegen_driverA_sine_test(WAVE_GEN_DRVA_BLK0, current_intensity);
    }
}

优势特点

1. 避免定时器冲突

  • 不再使用2ms定时器进行缓进缓出控制
  • 缓进缓出处理在电刺激处理函数中执行
  • 确保时序一致性

2. 精确控制

  • 基于方波周期计数,精度高
  • 每156个方波周期调整一次强度
  • 平滑的强度变化

3. 简单可靠

  • 逻辑清晰,易于理解
  • 不依赖复杂的定时器机制
  • 调试方便

时间分配

完整周期20秒

  1. 缓进阶段0-2秒强度0→128
  2. 保持阶段2-8秒强度保持128
  3. 缓出阶段8-10秒强度128→0
  4. 休息阶段10-20秒强度保持0

强度变化

  • 缓进每156个方波周期增加1个强度单位
  • 保持稳定在最大强度128
  • 缓出每156个方波周期减少1个强度单位

调试输出

系统会输出以下调试信息:

缓进缓出控制已启动 - 缓进阶段开始
缓进 - 强度增加到: 1
缓进 - 强度增加到: 2
...
缓进完成 - 进入保持阶段, 强度: 128
保持完成 - 进入缓出阶段
缓出 - 强度降低到: 127
缓出 - 强度降低到: 126
...
缓出完成 - 强度降至0
电刺激已停止

参数配置

EMS_Config_TypeDef ems_config = {
    .frequency = 100,        // 100Hz
    .duration = 1000,        // 1000ms
    .intensity = 128,        // 中等强度
    .rest_time = 100,        // 100ms休息时间
    .silent_time = 50,       // 50ms静默时间
    
    // 缓进缓出控制参数
    .ramp_up_time = 2,       // 缓进时间2秒
    .hold_time = 6,          // 保持时间6秒
    .ramp_down_time = 2,     // 缓出时间2秒
    .enable_ramp = 1         // 启用渐进控制
};

测试验证

1. 硬件测试

  • 用示波器观察梯形波形
  • 验证缓进缓出的平滑性
  • 检查时间精度

2. 软件测试

  • 通过UART观察调试输出
  • 确认强度变化正确
  • 验证阶段切换正常

3. 功能验证

  • 测试不同强度值
  • 验证时间分配
  • 确认循环工作正常

注意事项

1. 方波周期

  • 确保方波周期计算正确100微秒
  • 验证方波计数器正常工作
  • 注意计数器的溢出处理

2. 强度范围

  • 强度值范围0-255
  • 避免超出硬件限制
  • 考虑用户承受能力

3. 系统资源

  • 缓进缓出处理在电刺激处理中执行
  • 保持处理简洁高效
  • 避免影响其他功能

总结

修正后的缓进缓出功能:

  • 解决了定时器冲突问题
  • 采用方波周期计数方式
  • 实现了平滑的强度变化
  • 提供了舒适的刺激体验

现在您应该能在示波器上观察到清晰的梯形波形了!