天天看點

PWM控制小車車速

//初始小車以 20%占空比速度前進運作,K1 鍵可加速,K2 鍵可減速。最大可以 100%占空比速度運作。

#include "reg52.h"

typedef unsigned char u8;
typedef unsigned int u16;


//定義電機控制管腳
sbit MOTOA=P1^0;
sbit MOTOB=P1^1; //右側電機
sbit MOTOC=P1^2;
sbit MOTOD=P1^3; //左側電機

//定義按鍵管腳
sbit k1=P1^4;
sbit k2=P1^5;


u16 time_cnt=0; //定時器中斷計數次數
u16 freq=100; //PWM 輸出頻率 100HZ
u8 duty_cycle=20; //占空比 20%


//延時函數 10*us(us)

void delay_10us(u16 us)

{
    while(us--);
}



//ms 延時函數 ms

void delay_ms(u16 ms)

{
    u16 i,j;
    for(i=ms; i>0; i--)
        for(j=110; j>0; j--);
}
//定時器 0 初始化函數


//定時時間:0.1ms

void Time0_Init()

{
    TMOD|=0x01;
    TH0 = 0XFF;
    TL0 = 0X9C; //定時 0.1ms TR0 = 1;
    ET0 = 1;
    EA = 1;
}

void Car_ForwardRun()//前進
{
    MOTOA=1;
    MOTOB=0;
    MOTOC=1;
    MOTOD=0;
}

void Car_StopRun()//停止
{
    MOTOA=0;
    MOTOB=0;
    MOTOC=0;
    MOTOD=0;
}



//主函數 

void main()
{
    Time0_Init();
    
    while(1)
    {
        if(k1==0) //加速
        {
            delay_10us(1000);
            if(k1==0)
            {
                if(duty_cycle<100)
                    duty_cycle+=10;
            }
            while(!k1);
        }
        else if(k2==0) //減速
        {
            delay_10us(1000);
            if(k2==0)
            {
                if(duty_cycle>0) duty_cycle-=10;
            }
            while(!k2);
        }
    }
}
//定時器 0 中斷函數



void Time0_Isr() interrupt 1
{
    TR0 = 0; //關閉定時器 0
    TH0 = 0XFF;
    TL0 = 0X9C; //定時 0.1ms
    time_cnt++;    

    if(time_cnt>=freq)
        time_cnt=0;

    else if(time_cnt<=duty_cycle)
    {
        Car_ForwardRun();
    }

    else
    {
        Car_StopRun();
    }
    TR0 = 1;//開啟定時器 0
}
           

繼續閱讀