3.8 KiB
3.8 KiB
编码实现 - 振动马达驱动与反馈 (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;
}