# 缓进缓出功能说明（修正版）

## 问题分析

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

## 解决方案

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

### 1. 计算原理

根据您的分析：
- 每个方波周期：100微秒
- 2秒内方波周期数：2,000,000 ÷ 100 = 20,000个
- 强度从0增加到128，需要128个步进
- 每个步进的方波周期数：20,000 ÷ 128 ≈ 156.25个

### 2. 实现方式

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

## 核心变量

```c
// 缓进缓出控制变量
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秒）
```c
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秒）
```c
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秒）
```c
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;
```

## 调用方式

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

```c
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
电刺激已停止
```

## 参数配置

```c
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. 系统资源
- 缓进缓出处理在电刺激处理中执行
- 保持处理简洁高效
- 避免影响其他功能

## 总结

修正后的缓进缓出功能：
- 解决了定时器冲突问题
- 采用方波周期计数方式
- 实现了平滑的强度变化
- 提供了舒适的刺激体验

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

