基于51单片机T2的高精度PWM控制舵机

发布者:平和梦想最新更新时间:2025-09-23 来源: bilibili关键字:51单片机  高精度  PWM  控制舵机 手机看文章 扫描二维码
随时随地手机看文章

摘    要

虽然舵机的控制原理比较简单统一,但是PWM控制舵机的程序实现方式多种多样,有的使用延时(delay(ms)),有的使用定时器(time),而网上搜到的大部分控制代码却质量一般,控制精度都需要提高,就要对单片机定时器有详细的了解,否则延时将出现偏差。


本文使用单片机T2定时器,这个定时器大多数人很少使用它,而却不知道它有一个非常优秀的功能就是定时自动重载功能。利用这个功能能够更为精确的对定时器进行设定,可控制精度在1个机器周期(12M晶振下就是1us),T0、T1都需要手动重载,其精度无法很好的控制。


本程序硬件需求

/*------------------------------硬件需求: 12T系列单片机(8051内核)                     拥有T2定时器                     12M时钟晶振                     P2_0输出控制                     舵机角度范围在0~180 高电平范围0.5ms~2.5ms 20ms周期 --------------------------------*/

软件仿真演示(精准的50Hz的PWM信号)

程序设计思想:

根据舵机对PWM的需求,我们可以得知在20ms的周期中,我们需要在输出开始为高电平,在高电平结束时触发中断改为低电平,低电平结束后由触发中断将其设置为输出高电平,如此循环往复。


其中我们可以发现,我们的定时器是不断根据角度的设定而变化的,而定时器的工作需要在计时高电平与低电平间来回切换,这个定时器定时下次时间是通过装载在RCAP中的初始值决定了,于是我们完全可以通过设定RCAP2L,RCAP2H来改变下一次的定时时间,根据这个思想 定时器中断中便如此设计。            


if(SW)的分支语句 将20ms分为高低电平的定时 而且可以确定两者之和是20ms 也就是说完成了20ms的周期PWM波的输出。

cut-off

具体功能见代码 ,注释,有问题请在评论区留言

// Header:PWM舵机控制程序

// File Name:

// Author:程蒙蒙(QQ1058515967)

// Date:2018年9月12日

//Description:基于12T系列单片机且有T2定时器的单片机舵机控制程序

//,本程序控制精度高(1us),定时器自动控制舵机转动

/*------------------------------

硬件需求: 12T系列单片机(8051内核)

拥有T2定时器

12M时钟晶振

P2_0输出控制

舵机角度范围在0~180 高电平范围0.5ms~2.5ms 20ms周期

--------------------------------*/

#include <REGX52.H>

#define T2_PWMout P2_0  //舵机控制端

unsigned int PWMTimes=0;//高电平时间

unsigned char angle=0; //测试角度

void T2_Init();//初始化定时器2

void SetMotoangle(float angle);//设置舵机角度

void Delay100ms(); //@12.000MHz

void main()

{

bit SWdir=0;

T2_Init();//初始化定时器

while(1)//演示程序,舵机左右摆动

{

if(angle>180)SWdir=0;

else if(angle==0)SWdir=1;

SetMotoangle(SWdir?angle++:angle--);

Delay100ms();

}

}

void T2_Init()

{

unsigned int time=65536-20000;

RCAP2L = TL2 = time;            //initial timer2 low byte

RCAP2H = TH2 = time >> 8;       //initial timer2 high byte

TR2 = 1;                        //timer2 start running

ET2 = 1;                        //enable timer2 interrupt

EA = 1;                         //open global interrupt switch

}

void SetMotoangle(float angle)

{

//防止越界而损伤电机

if(angle > 175) angle = 175;

if(angle <5) angle = 5;

PWMTimes=500+angle*2000.0/180;//计算出高电平时间

}

/* Timer2 interrupt routine */

void tm2_isr() interrupt 5 using 1

{

static  bit SW=0;

unsigned int T2count;

TF2 = 0;//标志位清零

SW=~SW;//状态取反

T2_PWMout=SW;//更新输出

if(SW)//低电平时间

{

T2count=0xB1E0+PWMTimes;//0xB1E0即为20ms中断用时

RCAP2L=T2count;

RCAP2H=T2count>>8;

}

else//高电平时间

{

T2count=0-PWMTimes;

RCAP2L=T2count;

RCAP2H=T2count>>8;

}

}

void Delay100ms() //@12.000MHz

{

  unsigned char i, j;

  i = 195;

  j = 138;

  do

  {

    while (--j);

  }

  while (--i);

}


关键字:51单片机  高精度  PWM  控制舵机 引用地址:基于51单片机T2的高精度PWM控制舵机

上一篇:51单片机100例实例之02例
下一篇:51单片机按键检测--独立按键和矩阵按键

小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved