⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p1.c

📁 该程序用于控制电机的速度,通过占空比PWM来实现该功能.
💻 C
字号:
#include<reg52.h>
#include<intrins.h>
#include<math.h>

#define uchar unsigned char
#define uint unsigned char

uchar IC_0,IC_1;              //用于中断计数的变量
uchar flag;                   //标志,flag=1,INT0超前INT1;flag=0,INT0落后INT1;
uchar counter0=0;               //TIMER0的中断计数变量,
uint timecount0=0;               //
float circle_syn,circle_speed;     //同步信号的周期,速度信号的周期;
float error_P;        //两信号的相位差。
float critia_CP;               //周期和相位的标准差;critia_C=circle_syn/2000百分之一,相差0.01ms的时间
                                   
uchar PWM=0x32;               //占空比 PWM
uchar FPWM;
sbit out=P2^0;

uchar i,j;

/*********************************************************
 延时函数
*********************************************************/
void Delay(uint num)//延时函数
{
  while( --num );
}

void delayms(uchar ms)
{
  uchar i;
  while(ms--)
  for(i=0;i<120;i++)
   ;
}
/********************************
/mian()函数
/*******************************/
main()
{
  P1=0xff;
  P2=0xff;
  P3=0xff;
  P3=0x00;
  
   counter0=0;              
   timecount0=0;    

   TMOD=0x11;
   TH0=0xff;           //定时器0用来产生100HZ(0.1ms)的PWM波;
   TL0=0xb2;
   TH1=0x00;           //定时器1用来计算同步信号的周期circle_syn,并受INT0和INT1的双重控制;
   TL1=0x00;
   T2CON=0x00;        //定时器2用来计算速度信号的周期circle_speed,  不会让定时器2溢出
   TH2=0x00;
   TL2=0x00; 
   
   IT0=0;        //下降沿触发     INT0中断
   IT1=0;        //下降沿触发     INT1中断

   PX0=1;
   EX1=1;
   EX0=1;

   EA=1;
   ET0=1;
   TR0=1;
   TR1=0;
   TR2=0;
   
   while(1)

   { 
      

      if(timecount0<50)             //每20S周期的前5秒开INT0的中断允许,获取同步信号的周期 circle_syn;
		EX0=1;
 	    else 
		    EX0=0;  
     
     //critia_CP=circle_syn/200.0;     //取同步信号周期1/2000为标准差0.1ms

	 critia_CP=100.0;


    if(fabs(circle_syn-circle_speed)>critia_CP)
	   {
		  if(circle_syn<circle_speed)                   //转速不够快,频率还不够大
		    {PWM++; Delay(500);}
   		    else
			  {PWM--; Delay(500);	}
 		 
		}
		 else                                 //此时两信号周期基本一致
		    {
			  if(error_P>critia_CP)
			     {
				   PWM++;
				   for(i=0;i<(error_P/2);i++) ; 
				   PWM--;
				   for(j=0;j<(error_P/2);j++) ;  
				  
				 }
			    Delay(500);; 
			}  
/*******************************************************************************************************/

  /* if(circle_speed>circle_syn)                      //转速信号频率低, 加速
      { PWM++;Delay(2000);}
	     if((circle_speed-circle_syn)>50)
		    {PWM++;play();Delay(2000);}
	  //if((circle_speed-circle_syn)<150)
	  //   FPWM=PWM;                                 //固定此pwm值
		// Delay(3000000);
   	  }

	  while(fabs(circle_speed-circle_syn)<50)
	      {FPWM=PWM;Delay(2000);}
    if(circle_speed<circle_syn)                       //转的快了 减速
     {   	  
	    PWM=FPWM;play();Delay(2000);
     }
  if(error_P>30)
    {
	  PWM=FPWM+1;  for(i=0;i<(error_P/2);i++) ; 
	  PWM--;  for(j=0;j<(error_P/2);j++) ;  
	  PWM=FPWM;
	}
*/
	
    }
   delayms(300);

  
}
/******************************************
/TIMER0 中断处理函数   中断号 1
/******************************************/
void Time0(void) interrupt 1  //
{
  TH0=0xff;               //0.1ms  定时
  TL0=0xb2;
  counter0++;
  if(counter0<=PWM)
    out=0;
	else 
	    out=1;
   if(counter0==100)      //10ms 到  为一个周期
    {
	  counter0=0;
	  timecount0++;	 
	}
     if(timecount0==2000)	 
	    timecount0=0;
}
/******************************************
/TIMER1 中断处理函数   中断号 3 不能让timer1 产生中断
/******************************************/
void Time1(void) interrupt 3 
{  TR1=0;
   TH1=0x00;               //初始化
   TL1=0x00;
   TR1=1;
}
/******************************************
/TIMER2 中断处理函数   中断号 5 不能让timer2 产生中断
/******************************************/
void Timer2() interrupt 5
{ TR2=0;
  TF2=0;         //清TF2标志
  TH2=0x00;
  TL2=0x00;
  TR2=1;
}
/******************************************
/INT0 中断处理函数   中断号 0  获取同步信号的下降沿
/******************************************/
void  INT_0(void) interrupt 0
{
  IC_0++;
  if(IC_0>IC_1)
     flag=1;
	 else
	   flag=0;
    switch(IC_0)
	 {
	   case 1: TR1=1; break;
	   case 2: TR1=0; circle_syn=TH1*256+TL1; TH1=0x00; TL1=0x00; break;
	   case 3: { if(flag==1)    //同步信号超前,则启动定时器1
	               TR1=1;
				   else
				     {TR1=0;
					 error_P=TH1*256+TL1;       //同步信号滞后时,可算出相位差error_P;
					 }
				 break;
	           }
       case 4: TH1=0x00; TL1=0x00; IC_0=0; break;

   	   default:                   break;
	 }
}
/******************************************
/INT1 中断处理函数   中断号 2  获取速度信号的下降沿,始终中断允许
/******************************************/
void  INT_1(void) interrupt 2
{
  IC_1++;

    switch(IC_1)
	  {
	    case 1:TR2=1; break;
        case 2:TR2=0; circle_speed=TH2*256+TL2; TH2=0x00; TL2=0x00; break;                   
	    case 3: {while(EX0==1)              //只有INT0和INT1一起都中断允许的时候才执行
		           {
				     if(flag==0)        //速度信号超前,方可控制 定时器1
					    TR1=1;
						else
						   {
						      TR1=0;
							  error_P=TH1*256+TL1;  //计算出两信号的相位差
						   }
					}
				  ;
				  break;
		         }
	    case 4:  TH1=0x00; TL1=0x00; IC_1=0; break;
	  }
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -