STC12C简单的电机控制系统

STC12C简单的电机控制系统

点击查看全部代码
CPP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <STC12C5A60S2.h>

sbit MOTOR = P1^3; // 电机控制接在P1.3
sbit MOTOR_SWITCH = P1^2; // 按钮接在P1.2(修改为P1.2)

void Delay100ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 5;
j = 52;
k = 195;
do {
do {
while (--k);
} while (--j);
} while (--i);
}

void main() {
unsigned char motor_running = 0; // 标志位:电机是否运行
unsigned char button_prev; // 上一次按钮状态
unsigned int timer = 0; // 电机运行计时器(以100ms为单位)
unsigned char delay_start = 0; // 新增:延时启动标志
unsigned char delay_timer = 0; // 新增:延时启动计时器

P1M1 = 0x00; // 设置P1.3为推挽输出模式
P1M0 = 0x08; // 设置P1.3为推挽输出

MOTOR = 0; // 初始状态:电机停止
button_prev = MOTOR_SWITCH; // 初始化按钮状态

while (1) {
unsigned char button_curr = MOTOR_SWITCH; // 当前按钮状态

// 检测按钮按下并且是从低到高的状态变化(按钮按下时高电平)
if (button_curr == 1 && button_prev == 0) {
if (motor_running == 0 && delay_start == 0) {
delay_start = 1; // 启动延时
delay_timer = 20; // 设置2秒延时(100ms × 20 = 2秒)
} else if (motor_running == 1) {
motor_running = 0; // 停止电机运行
MOTOR = 0; // 停止电机
timer = 0; // 清空计时器
delay_start = 0; // 清除延时启动标志
}
}

// 处理延时启动
if (delay_start && delay_timer > 0) {
Delay100ms();
delay_timer--;
if (delay_timer == 0) {
motor_running = 1; // 设置电机运行状态
MOTOR = 1; // 启动电机
timer = 6; // 设定0.6秒运行时间
delay_start = 0; // 清除延时启动标志
}
}

// 如果电机正在运行,进行倒计时
if (motor_running && timer > 0) {
Delay100ms(); // 每次延时100ms
timer--; // 计时器递减
if (timer == 0) { // 如果计时器为0,停止电机
motor_running = 0; // 停止运行标志
MOTOR = 0; // 停止电机
}
}

button_prev = button_curr; // 更新按钮状态
}
}

代码功能概述

该代码实现了一个简单的电机控制系统。通过检测一个按钮的按下状态来启动或停止电机。程序包含以下功能:

  1. 按键检测 :按钮按下时触发动作。

  2. 延时启动 :按键触发后延迟一段时间再启动电机。

  3. 定时运行 :电机启动后运行固定时间(0.6秒),然后自动停止。


核心功能分析

  1. 按键检测
C
1
if (button_curr == 1 && button_prev == 0) {
  • 通过对比 button_currbutton_prev 检测按钮从低电平变为高电平的瞬间(假设按键按下时为高电平)。

  • 使用 MOTOR_SWITCH 定义的位变量直接读取 P1.2 引脚的电平状态。

  1. 延时启动
C
1
2
3
4
if (motor_running == 0 && delay_start == 0) {
delay_start = 1;
delay_timer = 20; // 设置2秒延时
}
  • 按钮触发时,判断电机是否处于停止状态。

  • 如果电机未运行且未处于延时启动状态,则进入延时启动逻辑。

  • 延时通过一个计数器 delay_timer 和一个标志位 delay_start 来实现,计时单位是 100ms

延时逻辑:

C
1
2
3
4
if (delay_start && delay_timer > 0) {
Delay100ms();
delay_timer--;
}
  • 每次调用 Delay100ms() 函数消耗 100ms。

  • delay_timer 减至 0 时,启动电机。

  1. 电机启动与停止
    电机启动:
C
1
2
3
4
motor_running = 1;
MOTOR = 1; // 启动电机
timer = 6; // 设置电机运行时间
delay_start = 0; // 清除延时启动标志
  • 设置电机为运行状态 (motor_running = 1)。

  • MOTOR 控制电机引脚,输出高电平启动电机。

  • 初始化运行计时器 timer,用于设定电机运行时间。

电机停止:

C
1
2
3
motor_running = 0;
MOTOR = 0; // 停止电机
timer = 0; // 清空计时器
  • 停止电机运行,将控制引脚 MOTOR 置为低电平。

  • 重置计时器。

  1. 定时运行
C
1
2
3
4
if (motor_running && timer > 0) {
Delay100ms();
timer--;
}
  • motor_running 标志为 1 且 timer > 0 时,定时器每次递减 1。

  • 定时单位是 100ms,定时器初始值为 6,因此电机运行时间为 $$100ms \times 6 = 600ms$$。
    timer == 0 时:

C
1
2
motor_running = 0;
MOTOR = 0;
  • 停止电机并清空运行标志。

硬件配置

  1. 电机连接
  • 电机控制引脚接在 P1.3,通过 MOTOR 宏定义,直接输出高/低电平控制电机。

  • 设置 P1.3 为推挽输出模式:

C
1
2
P1M1 = 0x00;
P1M0 = 0x08;
  1. 按钮连接
  • 按钮连接在 P1.2,通过 MOTOR_SWITCH 宏定义,读取引脚状态。

  • 假设按钮按下时引脚为高电平。


延时函数

C
1
void Delay100ms()  //@11.0592MHz
  • 实现了大约 100ms 的延时。

  • 通过嵌套循环来增加延时,具体延时值与晶振频率相关。


优点与改进建议

优点

  1. 逻辑清晰
  • 代码分为按钮检测、延时启动、电机控制三个模块,职责明确。
  1. 灵活性
  • 延时启动和电机运行时间的参数(如 delay_timertimer)可以轻松调整。
    改进建议
  1. 改进按钮检测的抗抖动
  • 增加软件去抖动机制,避免因电气噪声导致按钮误触发。例如:
C
1
2
3
4
5
6
if (button_curr == 1 && button_prev == 0) {
Delay100ms(); // 添加去抖延时
if (MOTOR_SWITCH == 1) {
// 确认稳定后才进行操作
}
}
  1. 优化延时函数
  • 使用定时器代替软件延时,以提高 CPU 利用率。
  1. 代码注释
  • 添加更多注释,特别是在硬件配置部分,便于其他开发者理解代码意图。

总结

该代码通过简单的按钮控制实现了电机的延时启动和定时运行功能,适用于初学者学习单片机的基本控制应用。若进一步优化,可提高可靠性和扩展性,例如加入更多按钮功能或使用定时器替代延时函数。