微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 单片机控制直流电机程序出错请高手指教

单片机控制直流电机程序出错请高手指教

时间: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;
}



Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top