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

120 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 编码实现 - 振动马达驱动与反馈 (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;
}
```
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes -->