Files
stc32g128k/Docs/60_coding/mod-motor.md

3.8 KiB
Raw Blame History

编码实现 - 振动马达驱动与反馈 (Docs/60_coding/mod-motor.md)

本文件对应振动马达异步时序控制的编码实现细节。

1. 对应代码源文件

  • App/main.c (定义马达引脚控制及 1ms 中断中的异步脉冲状态机处理)

2. 关键代码片段与逻辑实现

2.1 引脚控制宏与初始化

马达由引脚 P2.4 控制。配置模式为推挽输出:

sbit MOTOR = P2^4; // Pin 25

void Motor_Init(void) {
    // 将 P2.4 配置为推挽输出模式,默认输出低电平 0
    P2M1 &= ~(1 << 4);
    P2M0 |=  (1 << 4);
    MOTOR = 0;
}

2.2 异步定时脉冲时序控制 (Motor_Pulse_Process)

为了避免采用阻塞式的 Delay 函数占用 CPU我们在 1ms 定时中断中实现非阻塞状态机。 定义全局控制变量:

u16 motor_pattern_time = 0; // 阶段累计计数器
u8  motor_phase = 0;        // 振动阶段指示器
u8  motor_total_pulses = 0; // 当前告警所需触发的总脉冲数
u8  motor_pulse_count = 0;  // 已振动次数
u16 motor_on_ms = 0;        // 单次振动持续时间
u16 motor_off_ms = 0;       // 振动间隔休眠时间
bit motor_running_flag = 0; // 正在振动告警指示标志

Timer1_Isr (每 10ms 调用一次) 中驱动该状态机:

void Motor_Pulse_Process(void) {
    if (!motor_running_flag) {
        MOTOR = 0;
        return;
    }
    
    motor_pattern_time += 10;
    
    if (motor_phase == 0) {
        // 振动阶段
        MOTOR = 1;
        if (motor_pattern_time >= motor_on_ms) {
            MOTOR = 0;
            motor_pattern_time = 0;
            motor_phase = 1; // 切换到休眠阶段
        }
    } 
    else if (motor_phase == 1) {
        // 休眠间隔阶段
        MOTOR = 0;
        if (motor_pattern_time >= motor_off_ms) {
            motor_pattern_time = 0;
            motor_pulse_count++;
            
            if (motor_pulse_count >= motor_total_pulses) {
                // 已达到指定次数,停止当前周期振动
                MOTOR = 0;
                motor_running_flag = 0;
            } else {
                motor_phase = 0; // 继续下一次振动
            }
        }
    }
}

2.3 启动与重置接口

void Motor_Start_Alarm_Pattern(u8 type) {
    motor_pattern_time = 0;
    motor_phase = 0;
    motor_pulse_count = 0;
    
    switch (type) {
        case 0: // 🚪 门磁: 1 次短振 300ms
            motor_on_ms = 300; motor_off_ms = 5000; motor_total_pulses = 1;
            break;
        case 1: // 👤 PIR: 2 次短振 300ms
            motor_on_ms = 300; motor_off_ms = 200;  motor_total_pulses = 2;
            break;
        case 2: // 🔥 烟感: 3 次短振 200ms
            motor_on_ms = 200; motor_off_ms = 150;  motor_total_pulses = 3;
            break;
        case 3: // 🆘 紧急按钮: 1 次长振 800ms
            motor_on_ms = 800; motor_off_ms = 5000; motor_total_pulses = 1;
            break;
        case 4: // 💨 气体: 4 次短振 200ms
            motor_on_ms = 200; motor_off_ms = 100;  motor_total_pulses = 4;
            break;
        case 5: // 💧 水浸: 2 次长振 600ms
            motor_on_ms = 600; motor_off_ms = 300;  motor_total_pulses = 2;
            break;
        case 6: // 📳 振动: 3 次短振 150ms
            motor_on_ms = 150; motor_off_ms = 100;  motor_total_pulses = 3;
            break;
        case 7: // 🚨 本地主动 SOS: 循环长振
            motor_on_ms = 1000; motor_off_ms = 200; motor_total_pulses = 0xFF; // 近似无限循环
            break;
        default:
            return;
    }
    motor_running_flag = 1;
}

void Motor_Stop(void) {
    motor_running_flag = 0;
    MOTOR = 0;
}