1. 项目概述与硬件架构解析
这个基于STC89C52单片机的双直流电机控制系统,通过BTS7960驱动模块实现了电机的正反转PWM调速功能。系统采用模块化设计,主要由以下硬件单元构成:
- 主控单元:STC89C52单片机作为核心控制器,内部集成EEPROM用于参数存储
- 驱动模块:BTS7960半桥驱动芯片,最大支持43A峰值电流
- 显示单元:128x64分辨率的OLED显示屏,通过I2C接口通信
- 输入单元:4个独立按键用于速度调节和方向控制
- 电源模块:12V直流电源输入,经LDO稳压为5V供控制电路使用
BTS7960模块的典型接线方式如下:
code复制电机A接线:
P1.2 -> IN1 (方向控制1)
P1.3 -> IN2 (方向控制2)
P3.5 -> PWM1 (速度控制)
电机B接线:
P1.4 -> IN3
P1.5 -> IN4
P3.2 -> PWM2
2. 核心功能实现原理
2.1 PWM调速机制
系统采用定时器0中断产生PWM信号,关键参数配置如下:
c复制TMOD &= 0xF0; // 设置定时器0为模式1(16位定时器)
TH0 = 0x28; // 1ms中断周期(12MHz晶振)
ET0 = 1; // 使能定时器0中断
TR0 = 1; // 启动定时器0
PWM占空比通过time1/time2变量控制(0-99级),在中断服务程序中实现:
c复制void timer0() interrupt 1 {
if(MOTORARUN_L && (timeA++ < time1))
L1_PWM = 0; // 输出有效电平
else
L1_PWM = 1; // 输出无效电平
// 其他电机控制逻辑类似...
}
2.2 电机方向控制逻辑
方向控制采用H桥驱动原理,真值表如下:
| IN1 | IN2 | 电机A状态 |
|---|---|---|
| 0 | 1 | 正转 |
| 1 | 0 | 反转 |
| 0 | 0 | 刹车 |
| 1 | 1 | 自由停止 |
代码实现示例:
c复制void MotorA_Forward() {
INTPUT1 = 0;
INTPUT2 = 1;
MOTORARUN_L = 1;
}
void MotorA_Reverse() {
INTPUT1 = 1;
INTPUT2 = 0;
MOTORARUN_R = 1;
}
3. 关键外设驱动实现
3.1 OLED显示驱动
采用硬件I2C通信,核心函数包括:
c复制void Write_IIC_Command(u8 cmd) {
IIC_Start();
Write_IIC_Byte(0x78); // 器件地址
Write_IIC_Byte(0x00); // 命令标识
Write_IIC_Byte(cmd);
IIC_Stop();
}
// 显示汉字实现
void Show_Chinese(u8 page, u8 col, u8 index) {
for(u8 y=0; y<2; y++) {
Write_IIC_Command(0xB0 + page + y);
Write_IIC_Command(col >> 4);
Write_IIC_Command(col & 0x0F);
for(u8 x=0; x<16; x++) {
Write_IIC_Data(show2[x + y*16 + index*32]);
}
}
}
3.2 EEPROM参数存储
STC单片机内部EEPROM操作流程:
- 扇区擦除(4KB为单位)
- 字节编程
- 数据读取
关键函数实现:
c复制void Save_Speed(u8 speed1, u8 speed2) {
IapEraseSector(IAP_ADDRESS);
IapProgramByte(IAP_ADDRESS, speed1);
IapProgramByte(IAP_ADDRESS+1, speed2);
}
u8 Read_Speed(u8 motor) {
return IapReadByte(motor ? IAP_ADDRESS+1 : IAP_ADDRESS);
}
4. 系统软件设计要点
4.1 按键处理机制
采用状态机实现防抖检测:
c复制void Key_Scan() {
static u8 key_state = 0;
switch(key_state) {
case 0: // 等待按下
if(!KEY) key_state = 1;
break;
case 1: // 消抖确认
if(!KEY) {
key_state = 2;
key_press = 1;
} else {
key_state = 0;
}
break;
case 2: // 等待释放
if(KEY) key_state = 0;
break;
}
}
4.2 主程序控制流程
mermaid复制graph TD
A[系统初始化] --> B[外设初始化]
B --> C[读取EEPROM参数]
C --> D[显示待机界面]
D --> E{按键检测}
E -->|速度+| F[增加PWM占空比]
E -->|速度-| G[减小PWM占空比]
E -->|方向| H[切换电机转向]
F --> I[更新显示]
G --> I
H --> I
I --> E
5. 调试经验与常见问题
5.1 BTS7960使用注意事项
- 死区时间:输入信号切换时需要保证>1μs的死区时间
- 散热处理:大电流工作时必须加装散热片
- 电源滤波:建议在VCC和GND间并联100μF+0.1μF电容
5.2 典型问题排查
问题1:电机抖动不转
- 检查PWM频率是否合适(推荐1-20kHz)
- 测量驱动芯片使能端(EN)电平
- 确认电源功率足够(瞬时电流可达5A以上)
问题2:OLED显示异常
- 用逻辑分析仪检查I2C时序
- 确认上拉电阻(通常4.7kΩ)
- 检查电源电压(5V±10%)
问题3:参数无法保存
- STC EEPROM写入前必须擦除整个扇区
- 写入后需要延时5ms以上
- 避免频繁写入(寿命约10万次)
6. 性能优化建议
- PWM分辨率提升:
c复制// 将定时器设置为1T模式(STC特有功能)
AUXR |= 0x80; // 定时器0设置为1T模式
TH0 = (65536 - (MAIN_Fosc / 10000)) >> 8; // 10kHz PWM
- 运动控制优化:
c复制// 加入加速度控制
void Speed_Ramp(u8 target) {
while(current_speed != target) {
current_speed += (current_speed < target) ? 1 : -1;
Set_PWM(current_speed);
Delay_ms(10); // 10ms/步的加速度
}
}
- 抗干扰措施:
- 电机电源与控制电源分开走线
- 在单片机IO口与驱动模块间加入光耦隔离
- 电机外壳良好接地
这个项目完整实现了双直流电机的闭环控制,通过灵活的软件设计可以扩展到更多应用场景。实际使用时建议根据具体电机参数调整PWM频率和保护参数,对于需要精确控制的场合可以加入编码器反馈形成闭环系统。