程序如下:
/*晶振:11.0592,輸出的PWM直接給L298N以驅動電機,
通過調節(percent_l=90;)等號后的數值,與(Sum100)的比值,
為占空比,如上取90比100則輸出PWM波占空比為9/10的高電平,
1/10的低電平,低電平時間越長則速度越慢。
要注意的是調節#define Sum100的值可以調節PWM的總周期,
調節#define tim?200的值可以調節定時器的定時周期。*/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define MOTOR_C P1 //P1口作為電機的控制口。
#define BACK 0xfa //后退,0b1111 1010
#define FORWARD 0xf5 //前進,0b1111 0101
#define Sum 100 //總周期,為100倍的定時器時間大約27ms
#define tim 200 //初值數200約270us
sbit PWM_L=P1^0; //左電機前進
sbit PWM_R=P1^2; //右電機前進
sbit PWM_HL=P1^1; //左電機后退
sbit PWM_HR=P1^3; //右電機后退
void timer0_init(void);//定時器0初始化函數。
void timer1_init(void);//定時器1初始化函數。
void right(void); //前進右轉彎函數。
void left(void); //前進左轉彎函數。
void forward(void); //前進函數。
void stop(void); //停止
void Delayms(); //延時1ms
void Delay100ms(unsigned int d);//延時100ms
uchar percent_l=0; //(前進)左輪占空比。
uchar percent_r=0; //(前進)右輪占空比。
uchar percent_hl=0; //(后退)左輪占空比。
uchar percent_hr=0; //(后退)右輪占空比。
uchar run_time=0; //車輪運行一步的時間。
void main(void)
{
timer0_init();
timer1_init();
MOTOR_C=0x00;
//ENA=1;
//ENB=1;
while(1)
{
left();
Delay100ms(0.9);
right();
Delay100ms(0.9);
//back();
Delay100ms(0.9);
forward();
Delay100ms(0.9);
//stop();
}
}
void timer0_init(void)
{
TMOD=0X11;
TH0=(65536-tim)/256;
TL0=(65536-tim)%256;
EA=1;//開總中斷。 0000
ET0=1;//開定時器0中斷。
TR0=1;//啟動定時器0。
}
void timer1_init(void)
{
TH1=(65536-tim)/256;
TL1=(65536-tim)%256;
ET1=1;
TR1=1;
}
/**************前進方向****/
void right(void)
{
percent_l=50;//左輪速度快,最好去50以上
percent_r=0;//右輪速度慢。
percent_hl=0;
percent_hr=0;
}
void left(void)
{
percent_l=0;//左輪速度慢。
percent_r=50;//右輪速度快。
percent_hl=0;
percent_hr=0;
}
void forward(void)
{
percent_l=70;//左輪同速度。
percent_r=70;//右輪同速度。
percent_hl=0;
percent_hr=0;
}
void stop(void)
{
percent_l=0;//左輪零速度。
percent_r=0;//右輪零速度。
percent_hl=0;
percent_hr=0;
}
/**************中斷服務*******************/
void timer_0(void) interrupt 1 using 1
{
static uchar temp=0;//中斷次數計數。
TR0=0;
if(temp<Sum)
{ //關總中斷,屏蔽其他中斷。
if(temp<percent_l)
{
PWM_L=1; //左電機高電平。
}
else
{
PWM_L=0; //左電機低電平。
}
if(temp<percent_r)
{
PWM_R=1; //右電機高電平。
}
else
{
PWM_R=0; //右電機低電平。
}
}
else
{temp=0;}
temp++;
TH0=(65536-tim)/256;
TL0=(65536-tim)%256; //實現計數。
TR0=1; //開總中斷。
}
void timer1 ( void ) interrupt 3 using 2
{
static uchar temp1=0;
TR1=0; //關總中斷,屏蔽其他中斷。
if(temp1<Sum)
{
if(temp1<percent_hl)
{
PWM_HL=1;//左電機高電平。
}
else
{
PWM_HL=0;//左電機低電平。
}
if(temp1<percent_hr)
{
PWM_HR= 1;//右電機高電平。
}
else
{
PWM_HR= 0;//右電機低電平。
}
}
else
{
temp1=0;
}
temp1++;
TH1=(65536-tim)/256;
TL1=(65536-tim)%256; //實現計數。
TR1 = 1; //開總中斷。
}
void Delayms(void)
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=23;b>0;b--)
for(a=13;a>0;a--);
}
void Delay100ms(unsigned int d)
{
unsigned int a,b,c;
for(c=d;c>0;c--)
for(b=60;b>0;b--)
for(a=130;a>0;a--);
}
|