天天看點

51單片機 精确控制舵機pwm

//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;

}

用模拟器調試,應該可以,沒有在實際的舵機上調試,應該超不多。

繼續閱讀