一、核心原理
舵机控制只需要一个PWM信号:
- 周期:20ms(50Hz)
- 高电平时间:0.5ms~2.5ms
- 对应角度:0°~180°
二、所需材料
| 材料 | 数量 | 说明 |
|---|---|---|
| 51单片机最小系统板 | 1个 | STC89C52/STC12C5A60S2等 |
| SG90舵机 | 1个 | 最常用的小型舵机 |
| 杜邦线 | 3根 | 连接用 |
| USB转TTL模块 | 1个 | 下载程序用 |
| 5V电源 | 1个 | 舵机需要单独供电 |
三、电路连接
舵机红线 → 5V电源正极
舵机棕线 → 5V电源负极
舵机橙线 → P1.0(信号线)
单片机VCC → 5V电源正极
单片机GND → 5V电源负极
重要 :舵机电流较大(约200-500mA),不要直接从单片机引脚取电!
四、代码
c
#include <reg52.h>
sbit Servo = P1^0; // 舵机信号线接P1.0
// 延时函数(12MHz晶振)
void Delay_us(unsigned int us) {
while(us--) {
_nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();
}
}
// 延时函数(毫秒级)
void Delay_ms(unsigned int ms) {
unsigned int i, j;
for(i=0; i<ms; i++)
for(j=0; j<123; j++);
}
// 控制舵机角度
void Servo_Angle(unsigned char angle) {
unsigned int high_time;
// 角度转换为高电平时间(0.5ms~2.5ms)
// 公式:高电平时间 = 500 + angle * (2000/180) 微秒
high_time = 500 + angle * 11; // 近似计算
// 产生一个PWM周期
Servo = 1; // 高电平开始
Delay_us(high_time); // 保持高电平
Servo = 0; // 低电平
Delay_us(20000 - high_time); // 补足20ms周期
}
void main() {
unsigned char angle = 90; // 初始角度90度
while(1) {
// 从0度到180度扫描
for(angle = 0; angle <= 180; angle++) {
Servo_Angle(angle);
Delay_ms(20); // 每个角度停留20ms
}
// 从180度到0度扫描
for(angle = 180; angle > 0; angle--) {
Servo_Angle(angle);
Delay_ms(20);
}
}
}
五、进阶代码
c
#include <reg52.h>
sbit Servo = P1^0;
unsigned int high_time = 1500; // 默认1.5ms(90度)
// 定时器0初始化(12MHz晶振)
void Timer0_Init() {
TMOD |= 0x01; // 定时器0,模式1(16位)
TH0 = 0xFE; // 定时0.5ms初值
TL0 = 0x33;
ET0 = 1; // 允许定时器0中断
EA = 1; // 开总中断
TR0 = 1; // 启动定时器0
}
// 设置舵机角度(0-180度)
void Set_Angle(unsigned char angle) {
// 角度转换为高电平时间(0.5ms~2.5ms)
// 500us + angle * (2000/180)us
high_time = 500 + angle * 11; // 近似值
}
// 定时器0中断服务函数
void Timer0_ISR() interrupt 1 {
static unsigned int count = 0;
// 重装初值(0.5ms)
TH0 = 0xFE;
TL0 = 0x33;
count++;
if(count < high_time/500) { // 高电平时间
Servo = 1;
} else {
Servo = 0;
}
if(count >= 40) { // 20ms周期(40*0.5ms)
count = 0;
Servo = 1; // 新周期开始
}
}
void main() {
unsigned char angle = 0;
Timer0_Init();
while(1) {
// 示例:让舵机在0、90、180度之间切换
Set_Angle(0); // 0度
Delay_ms(1000);
Set_Angle(90); // 90度
Delay_ms(1000);
Set_Angle(180); // 180度
Delay_ms(1000);
}
}
六、制作步骤
-
硬件连接
舵机红线 → 5V电源 舵机棕线 → GND 舵机橙线 → P1.0 -
程序烧录
- 使用USB转TTL模块连接单片机
- 用STC-ISP软件下载程序
-
测试
- 上电后舵机会自动转动
- 观察是否平滑转动0°→180°→0°
参考代码 最简单DIY基于51单片机的舵机控制器 www.youwenfan.com/contentcst/160854.html
七、常见问题解决
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 舵机不转 | 电源不足 | 使用独立5V电源,不要用USB供电 |
| 抖动严重 | PWM信号不稳定 | 改用定时器中断方式 |
| 角度不准 | 延时误差 | 调整high_time计算公式 |
| 只转一边 | 信号线接反 | 检查橙线是否接P1.0 |
八、扩展功能(可选)
- 电位器控制:加一个电位器,实时调节角度
- 按键控制:用两个按键控制角度增减
- 多舵机控制:使用PCA/PWM模块控制多个舵机
- 串口控制:通过电脑串口发送角度值
九、最简零件清单
- STC89C52最小系统板 ×1(5元)
- SG90舵机 ×1(8元)
- USB转TTL模块 ×1(5元)
- 杜邦线若干(2元)