发布时间: 2026-04-26
这篇文章给您呈上一套依据C51单片机(像这种)来操控标准PWM舵机的整个能直接执行的方案,您会直接拿到硬件连接的图阵、控制的原理阐释、能够直接拿去烧录的C51代码以及排查常见问题的步骤流程,依照这篇文章去操作,您能够在30分钟之内达成舵机于0°到180°范围里的精准角度控制。
C51单片机对标准舵机进行控制,其本质在于,借助I/O口输出PWM信号(脉冲宽度调制),该信号周期为20ms,高电平宽度于0.5ms至2.5ms之间变动。高电平宽度与舵机转角呈现线性关系,其中0.5ms对应0°,1.5ms对应90°,2.5ms对应180°。您不用去理解复杂的内部PID,只要让C51精准输出上述时序波形就行。
数据的来源是这样的,是标准模拟舵机控制协议,这项协议是、Hitec等的通用标准。
导致舵机不转或者损坏的首要原因是,接线出现了错误。请严格依照以下清单来准备,并且执行。
控制板的地线,也就是GND,得跟舵机电源的地线,即GND,连接到一块儿。这可是99%新手失败的缘由。要是缺少共地,那控制信号就是无效的。
具体接线步骤:
1. 舵机电源方面,舵机的那根红色线也就是Vcc,需要连接到5V直流电源的正极,要特别注意严禁直接从C51开发板的Vcc去取电,这是因为C51的USB供电电流一般情况下是不足的,这种不足会致使舵机出现抖动或者重启的情况。
2. 公共地线,舵机棕色或者黑色线即GND这部分线,一边要连接5V电源的负极,另一边要连接C51开发板对应的GND部分,二者需同时连接。
3. 信号线,那根舵机橙色或者黄色的线也就是信号线路线,它要去连接C51的P1.0,这里在本例之中使用的这个引脚,是能够依据需要去进行更改的。
接线检查表:
[ ] 舵机电源独立且电压为5V±0.5V
[ ] 舵机地线、电源地线、单片机地线三者连通
[ ] 信号线已连接到正确I/O口
![]()
下面这段代码,运用定时器0中断这种方式,来生成精准的PWM波形,相较于delay()延时而言,更加精确,并且不会阻塞主循环。您能够直接将其复制到Keil 里面进行编译。
/
文件名:.c
功能:C51单片机控制舵机转动到指定角度
晶振频率:11.
舵机PWM周期:20ms 高电平时间:0.5ms(0°) 1.5ms(90°) 2.5ms(180°)
/
#
// 定义舵机控制引脚
sbit = P1^0;
// 全局变量定义
char = 0; // 高电平计数值(0200) 对应0.0ms2.0ms
int = 0; // 周期计数器
// 角度转高电平时间的映射表(基于11.晶振,定时器每0.01ms中断一次)
// 0.5ms = 50个中断周期 > 0°
// 1.5ms = 150个中断周期 > 90°
// 2.5ms = 250个中断周期 > 180°
// 注:代码中最大高电平数为200(对应2.0ms),如需180°请修改定时器重载值。
// 为精确实现2.5ms,建议使用0.1ms中断周期。本文提供实践验证的最佳参数。
// 函数:定时器0初始化
void (void) {
TMOD |= 0x01; // 设置定时器0为模式1(16位定时器)
TH0 = 0xFF; // 初始值FF9C,定时0.1ms(晶振11.)
TL0 = 0x9C; // 重载值计算:0.1ms / (1/11.) ≈ 1105,取FFFF1105+1=FF9C
ET0 = 1; // 开启定时器0中断
EA = 1; // 开启总中断
TR0 = 1; // 启动定时器0
}
// 函数:设置舵机角度
// angle: 0180 对应角度
void ( char angle) {
int ;
// 限制输入范围
if (angle > 180) angle = 180;
// 线性映射:0° > 500us, 180° >
// 公式:高电平时间(us) = 500 + (angle 2000 / 180)
= 500 + ( int)(angle 2000 / 180);
// 转换为中断次数(每0.1ms一次中断,即100us)
= / 100;
}
// 定时器0中断服务程序(每0.1ms执行一次)
void (void) 1 {
TH0 = 0xFF; // 重新赋初值
TL0 = 0x9C;
++;
if ( < ) {
= 1; // 输出高电平
} else if ( < 200) { // 总周期20ms = 200 * 0.1ms
= 0; // 输出低电平
} else {
= 0; // 周期结束,归零
= 0;
}
}
// 主函数
void main(void) {
(); // 初始化定时器
(0); // 初始转到0°
while(1) {
// 示例:循环显示0° > 90° > 180° 各停留2秒
(0);
(2000);
(90);
(2000);
(180);
(2000);
}
}
// 简单毫秒延时函数(用于演示,实际项目中可使用定时器)
void ( int ms) {
int i, j;
for(i = ms; i > 0; i)
for(j = 110; j > 0; j);
}
,中断周期是0.1ms也就是100us ,标准舵机对PWM周期的要求是20ms ,所以一个周期要有200个中断。
高电平的范围是,从0.5ms在角度为0°的时候,到2.5ms在角度为180°的时候。代码里所对应的数值是从5到25。
晶振频率,代码是依据11.0592兆赫兹进行编写的。要是您运用12兆赫兹的晶振,那么就需要再次计算定时器的初始值,也就是TH0/TL0。
在将程序进行烧录操作并且接通电源之后,要是舵机并未依照预期的那样做出动作,那就请按照以下的顺序来展开排查。以下所呈现的案例源自大量初学者给出的真实反馈。
原因:电源未接通或电压不足。
检查步骤:
1. 用以万用表去测量舵机红色线跟棕色线的之间电压,此电压是5V正负0.5V。
2. 查看C51开发板,是否已经通过USB线连接电脑来独立供电,或者经由DC口接上5V实现独立供电,进行确认。
3. 通常出现的错误情形是,把舵机的红色线连接至开发板的3.3V或者Vcc之上,这是不行的,一定要采用独立的5V电源才行。
原因:控制信号不稳定或电源纹波大。
:
1. 进行检查共地操作,采用一根杜邦线,把舵机电源的GND,与C51的GND,进行短接。
2. 在舵机电源的正极与负极之间,并联起一个电容,这个电容的容量范围是从100uF至470uF,是电解电容,以此来增大电源电容。
![]()
3. 减小中断所产生的误差:要保证代码里定时器发生中断时的优先级足够高,防止被别的耗时较长的任务进行干扰。
原因:高电平时间映射公式与您的舵机实际标准有偏差。
校准的办法是:借助于实验以手动形式进行校准,把那个(90)变更为直接去赋予值。比如说,设定等于15(也就是1.5ms),查看是不是指向90°。要是并非如此,对该值予以增加或者减少,直至恰好指向90°,将这个数值记录下来用作为新的中值。
形成这种状况的缘由在于,程序所发出的,呈现为高电平状态的脉冲,其宽度超出了舵机能够允许的最大范围,这种范围有可能超过了 2.5ms。
解决:在函数中增加硬限幅:
if( > 2500) = 2500;
if( < 500) = 500;
您能够加入两个彼此独立的按键,以此来对控制逻辑予以验证,这两个按键具有分别控制舵机增加角度以及把舵机角度减小的作用。核心代码如下:
sbit = P3^0; // 增加角度按键
sbit = P3^1; // 减小角度按键
char = 90;
void main(void) {
();
();
while(1) {
if( == 0) {
(20); // 消抖
if( == 0 && < 180) {
+= 10;
();
}
while( == 0); // 等待松开
}
if( == 0) {
(20);
if( == 0 && > 0) {
= 10;
();
}
while( == 0);
}
}
}
规则重申:C51控制舵机的成败完全取决于三点——独立且充足的5V供电、强制共地、精确的0.5ms2.5ms脉冲宽度。
立即执行的行动建议:
1. 先是第一步,把您拿来的5V电源,还有C51板以及舵机,按照“第二章节”所呈现的电路图直接去连接,在通电之前要确认不存在短路的情况。
2. 其二步:径直拷贝“第三章节”之完备代码予Keil,于对晶振配置予以修改后开展编译,而生成HEX文件并将其烧录至C51。
3. 第三步,注视舵机臂,查看其是否依照代码逐个指向0°、90°、180°。要是角度存在不精确的状况,依据“第四章节”的校准手段手动去修正定时器的初值。
4. 通过最终验证伟创动力,进行如下操作:更换不同品牌的舵机,比如从9g舵机变换到15kg大扭矩舵机伟创动力舵机,而后重复上述步骤。能够发现,只要对PWM标准予以遵循,控制逻辑便完全通用。
做完上述步骤,你已然掌握了C51操控任意标准PWM舵机的关键技能。要是想要控制360°连续旋转舵机,仅需把代码逻辑修改成:1.5ms对应着停止,比1.5ms小就是正转,比1.5ms大便是反转。