单片机控制直流电机程序出错请高手指教
时间:10-02
整理:3721RD
点击:
最近正在做单片机控制直流电机的东西,由于是新手,啥都是现学的,在定时器程序处总是出现错误,下面是我写的总程序,要求能实现对直流电机控速,能设定转速(我用L298驱动芯片驱动电机),设定转速时间并计时,并用液晶显示,液晶我用的1602,还有测速,测速这个模块还没开始,先不说。出现的问题是我用了两个定时器,定时器0用于对设定的时间倒计时并在液晶上显示,50ms中断一次,实际中定时一般是用分钟,可为了试验仿真方便程序中是用秒倒计时的;定时器1用于产生PWM波控制电机转速,100us中断一次,周期是300ms,用按键控制两个定时器同时开启,可是为什么仿真的时候,总是先倒计时,等到倒计时结束后,定时器1才输出PWM波?本应该在计时中就一起输出PWM波控速,等计时结束正好关掉电机。求高手指点,在此感激不尽。
#include<reg52.h> //此程序能够成功显示vst、tst、vmt、tmt
#define uint unsigned int
#define uchar unsigned char
uchar code table[]="Vst: ";
uchar code table1[]="Tst: ";
uchar code table2[]="Vmt: ";
uchar code table3[]="Tmt: ";
uchar code table4[]="0123456789";
sbit pwm=P2^2;
sbit right=P2^3;
sbit left=P2^4;
sbit lcden=P2^1;
sbit lcdrs=P2^0;
sbit s1=P3^0;
sbit s2=P3^1;
sbit s3=P3^2;
sbit s4=P3^3;
sbit s5=P3^4;
sbit s6=P3^5;
sbit s7=P3^6;
sbit s8=P3^7;
sbit led1=P1^0;
sbit led2=P1^1;
uchar num2,s1num,bai,shi,ge;
uint vs,ts,x,y,z,t,N;
void delayms(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void write_com(uchar com)
{
lcdrs=0;
P0=com;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
void write_date(uchar date)
{
lcdrs=1;
P0=date;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
void display_vs()
{
bai=vs/100;
shi=vs%100/10;
ge=vs%10;
write_com(0x80+4);
write_date(table4[bai]);
delayms(1);
write_com(0x80+5);
write_date(table4[shi]);
delayms(1);
write_com(0x80+6);
write_date(table4[ge]);
delayms(1);
}
void display_ts()
{
bai=ts/100;
shi=ts%100/10;
ge=ts%10;
write_com(0x80+12);
write_date(table4[bai]);
delayms(1);
write_com(0x80+13);
write_date(table4[shi]);
delayms(1);
write_com(0x80+14);
write_date(table4[ge]);
delayms(1);
}
void init() //初始化函数
{
uchar n;
pwm=0;
right=0;
left=0;
vs=0;
ts=0;
s1num=0;
lcden=0;
write_com(0x38); //初始化1602液晶
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(n=0;n<6;n++) //显示vst:、tst:、vmt:、tmt:
{
write_date(table[n]);
delayms(5);
}
write_com(0x80+8);
for(n=0;n<6;n++)
{
write_date(table1[n]);
delayms(5);
}
write_com(0x80+0x40);
for(n=0;n<6;n++)
{
write_date(table2[n]);
delayms(5);
}
write_com(0x80+0x40+8);
for(n=0;n<6;n++)
{
write_date(table3[n]);
delayms(5);
}
TMOD=0X11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-100)/256;
TL1=(65536-100)%256;
EA=1;
ET1=1;
ET0=1;
}
下面是键盘控制,都是对vs、ts的值进行设定,这里给略去了。占空间只留下两个按键是控制正反转的,同时控制两个定时器的开启
void keyscan()
{
if(s6==0) //按键s6,控制电机正转
{
delayms(5);
if(s6==0)
{
while(!s6);
right=1;
left=0;
}
}
if(s7==0) //按键s7,控制电机反转
{
delayms(5);
if(s7==0)
{
while(!s7)
right=0;
left=1;
}
}
}
void main() //主函数
{
init();
while(1)
{
keyscan();
if(right==1|left==1)
{
TR1=1;
TR0=1;
}
if(ts==0)
{
TR0=0;
right=0;
left=0;
}
}
}
void T0_time() interrupt 1 //定时器0中断,对设定的时间进行倒计时函数
{
TH0=(65536-50000)/256;
TL0=(65535-50000)%256;
x=ts/100;
y=ts%100/10;
z=ts%10;
write_com(0x80+0x40+12);
write_date(table4[x]);
delayms(1);
write_com(0x80+0x40+13);
write_date(table4[y]);
delayms(1);
write_com(0x80+0x40+14);
write_date(table4[z]);
delayms(1);
num2++;
if(num2==20)
{
num2=0;
if(ts>0)
ts--;
else
ts=0;
}
}
void T1_time() interrupt 3 //把pwm波的周期定为300ms,占空比分3000级可调,这样定时器T0 每 0.1ms产生一次定时中断
{
TH1=(65536-100)/256;
TL1=(65536-100)%256; //3000次后进入下一个pwm
N++;
if(N>=3000)
N=0;
if(N<=vs)
pwm=1;
else
pwm=0;
}