# 编码实现 - 振动马达驱动与反馈 (Docs/60_coding/mod-motor.md) 本文件对应振动马达异步时序控制的编码实现细节。 ## 1. 对应代码源文件 * [App/main.c](file:///c:/workfile/105/stc32g12k128/App/main.c) (定义马达引脚控制及 1ms 中断中的异步脉冲状态机处理) ## 2. 关键代码片段与逻辑实现 ### 2.1 引脚控制宏与初始化 马达由引脚 `P2.5` 控制。配置模式为推挽输出: ```c sbit MOTOR = P2^5; void Motor_Init(void) { // 将 P2.5 配置为推挽输出模式,默认输出低电平 0 P2M1 &= ~(1 << 5); P2M0 |= (1 << 5); MOTOR = 0; } ``` ### 2.2 异步定时脉冲时序控制 (Motor_Pulse_Process) 为了避免采用阻塞式的 `Delay` 函数占用 CPU,我们在 1ms 定时中断中实现非阻塞状态机。 定义全局控制变量: ```c 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 调用一次) 中驱动该状态机: ```c 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 启动与重置接口 ```c 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; } ```