51单片机 精确控制舵机pwm

/*
实现特定pwm 100级别舵机控制输出,其他级别也很简单,太低了可能不行


前提条件:
1. 舵机控制频率是 50hz
2. 舵机占空比时间是0.5 - 2.5 ms
算法:
0.5 - 2.5 跨度是2ms (2000 us)
要实现精确控制,100级别, 2ms / 100 = 20us,定时器基准时间就是20us
内部计数器pwm_cnt 取值范围是25 - 125 产生0.5 ms - 2.5ms的高电平时间
低电平,不精确调整,采用500us定时基准,有一定的误差,但是应该不影响。
*/


//TL0 = 0xEE; //设置定时初值
//TH0 = 0xFF; //设置定时初值 20us 重装值


//TL0 = 0x33; //设置定时初值
//TH0 = 0xFE; //设置定时初值 500 us重装值
unsigned char pwm_flag;
unsigned char pwm_cnt;


unsigned char duty_cycle; //舵机占空比 (0 - 100)
sbit pwm_out = P1 ^ 1;


void timer0_isr(void) interrupt 1 using 1
{
    if(pwm_flag)
    {
        TL0 = 0xEE;
        TH0 = 0xFF;//重装20us值
        pwm_cnt++;
        if(pwm_cnt == duty_cycle + 25)
        {
            pwm_out = 0;
            pwm_cnt = 0;
            pwm_flag = 0;   //翻转pwm_out
        }else
        {
            pwm_out = 1;
        }


    }else
    {
        TL0 = 0x33;
        TH0 = 0xFE;//重装500us值     
        pwm_cnt++;
        if(pwm_cnt == 35)
        {
            pwm_cnt = 0;
            pwm_out = 1;
            pwm_flag = 1;   //翻转pwm_out
        }else{
            pwm_out = 0;
        }
    }


}


void Timer0Init(void) //20微秒@11.0592MHz
{
    TMOD = 0x01;                    //set timer0 as mode1 (16-bit)
    TL0 = 0xEE;                     //initial timer0 low byte
    TH0 = 0xFF;                //initial timer0 high byte
    TR0 = 1;                        //timer0 start running
    ET0 = 1;                        //enable timer0 interrupt
    EA = 1;                         //open global interrupt switch


    pwm_cnt = 0;
    pwm_flag = 1;               // 高电平先行
}
void main(void)
{
    Timer0Init();
    duty_cycle = 99;
    while(1);
    return;

}


用模拟器调试,应该可以,没有在实际的舵机上调试,应该超不多。

你可能感兴趣的:(舵机,pwm,51)