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

📄 电机测速.c

📁 直流电机测速程序 电机需带码盘 精度高 可直接设置转数 短时间内电机达到所设定的 速度
💻 C
字号:
#include<reg52.h>

sbit a4=P2^4;
sbit a5=P2^5;
sbit a6=P2^6;
sbit z0=P3^6;  //正转口//
sbit z1=P3^7;  //反转口//

unsigned char i,j,k,l,m,n;
unsigned char key,count,flag=0,flag_1,flag_2=1,flag_3=0,flag_4=0,num[8];
unsigned int shijian=0,mc=0,t,rps_int=0,time=0,time_1=0,hol=1;  //shijian是产生mc个脉冲用的时间;time总时间;rps电机实际速度//
float rps=0.0,v,dv,dv_1,dv_2;                                                //设置的速度v//

void delay(count)	//延时count MS//
{
 for(i=0;i<count;i++)
 for(j=0;j<125;j++);
}

unsigned char KEYZHI()	  //按键扫描程序//
 {
  k=0;
  while(k==0)								//扫描//
   {
    do
     { P1=0xf0; }
    while ((0xf0&P1)==0xf0) ;			  //有按下?有则跳出do……while循环//
    delay(5);							  //延时,防干扰//
    if((0xf0&P1)==0xf0) k=0;			  //真的按下去了吗?延时后再作判断//
    else  k=1;
   }

   P1=0x0f;
   switch(P1)                     //扫描行,得出行号j//
     {
      case 0x0e: j=0;break;
      case 0x0d: j=1;break;
      case 0x0b: j=2;break;
      case 0x07: j=3;break;
      default:  break;
     }

    P1=0xf0;			//扫描列,得出列号i//
    switch(P1)
      {
       case 0xe0: i=0;break;
       case 0xd0: i=1;break;
       case 0xb0: i=2;break;
       case 0x70: i=3;break;
       default:   break;
      }

     return(i+j*4);		//返回键值,供下面作数据处理//

}

void DF()	//等待按键释放程序//
{
 n=0;
 while(n==0)
  {
    do
    { P1=0x0f; }
    while((0x0f&P1)!=0x0f);	  //等待按键释放,即若没有放开则一直循环//
    delay(5);		//放开键后消抖//
    P1=0x0f;
    if((0x0f&P1)!=0x0f)		  //真的放开了吗?延时后再次判断//
	  n=0;
    else
	  n=1;
  }
}

void Int0(void) interrupt 0           //外部中断0 测脉冲个数//
 {
  mc++;                                     //脉冲累加//
  TR1=1;                                    //定时器1启动//
//  if(flag==1) 								//测周入口//
//   {
//    if(flag_1==1){TH1=0x00;TL1=0x00;shijian=0;mc=0;flag_1=0;}		//第一mc进来 准备测周 时间清零//
//
//    else
//     {
//      TR1=0;rps=1000000/(13.0*((TH1<<8)+TL1));
//	  dv=v-rps;
//      t=t+114*dv;
//      rps_int=100*rps;
//      num[7]=rps_int%10;
//      num[6]=(rps_int/10)%10;
//      num[5]=(rps_int/100)%10;
//      num[4]=(rps_int/1000)%10;
//     }
//   }
 }

void Int1(void)	interrupt 2           //外部中断1 自动//
{
// time_1=0; dv=0; t=13667;
// if(time_1==100) t=12080;
// if(time_1==200) t=50000;
   if(flag_4==0) {t=13667;flag_4=1;}
   else
    {
     if(flag_4==1){t=12080;flag_4=2;}
     else {t=50000;flag_4==0;}
    }    
}

void Timer0(void) interrupt 1         //定时器0中断 产生PWM波 使电机转动//
{

  switch(l*2+hol)
  {
   case 0: TH0=(65536-t)>>8; TL0=(65536-t)-(((65536-t)>>8)<<8);z1=0; z0=1; hol=1; break;  //正转 高电平//
   case 1: TH0=(15536+t)>>8; TL0=(15536+t)-(((15536+t)>>8)<<8);z1=0; z0=0; hol=0; break;  //正转 低电平//
   case 2: TH0=(65536-t)>>8; TL0=(65536-t)-(((65536-t)>>8)<<8);z0=0; z1=1; hol=1; break;  //反转 高电平//
   case 3: TH0=(15536+t)>>8; TL0=(15536+t)-(((15536+t)>>8)<<8);z0=0; z1=0; hol=0; break;  //反转 低电平//
  }
}


void Timer1(void) interrupt 3          //定时器1中断 计时50MS一次//
 {
  TH1=0x3c;
  TL1=0xaf;
  shijian=shijian+1;
  time_1=time_1+1;
  if(shijian==1)
   {
//    if(mc/2.4<42) { flag=1; flag_1=1;}                    //低速区 测周//
//    else                                  //高速区 测频//
//	 {
      rps=mc/0.65;
      rps_int=10*rps;
      num[7]=rps_int%10;
      num[6]=(rps_int/10)%10;
      num[5]=(rps_int/100)%10;
      num[4]=(rps_int/1000)%10;
      dv=v-rps;
      
      if(flag_3==0){dv_1=dv;flag_3=1;}
      else {dv_2=dv;flag_3=0;}
      
      t=t+8*dv+0.7*(dv_1-dv_2);
      shijian=0;
      mc=0;
//	  }
   }

 }

void Timer2(void) interrupt 5	//定时器2中断 选通及显示//
 {

    TH2=0xf8 ;
    TL2=0x2f ;
    m=P2;
    m=0x70 & m;				 //m为位选通变量//
    switch(m)			  //扫描显示;a6,a5,a4为下次选通先给P2高位赋值//
      {
	   case 0x60 : P2=num[7];a6=1; a5=1; a4=1;  break;
	   case 0x70 : P2=num[0];a6=0; a5=0; a4=0;  break;
	   case 0x00 : P2=num[1];a6=0; a5=0; a4=1;  break;
	   case 0x10 : P2=num[2];a6=0; a5=1; a4=0;  break;
	   case 0x20 : P2=num[3];a6=0; a5=1; a4=1;  break;
	   case 0x30 : P2=num[4];a6=1; a5=0; a4=0;  break;
	   case 0x40 : P2=num[5];a6=1; a5=0; a4=1;  break;
	   case 0x50 : P2=num[6];a6=1; a5=1; a4=0;  break;
      }

}

void main()
{                          //
  TMOD=0X11;               //
  EA=1;                    //
  EX0=1;                   //外部中断0打开//
  EX1=0;                   //外部中断1//
  IT0=1;                   // 设置电平触发方式//
  ET0=1;                   //
  ET1=1;                   //
  ET2=1;                   //
  TR0=0;                   //
  TR1=0;
  TR2=1;
  TH0=0xc5;
  TL0=0x67;
  TH1=0x3c;
  TL1=0xaf;

  CP_RL2=1;
  C_T2=0;
  EXEN2=0;
  TH2=0xf8 ;
  TL2=0x2f ;

 for(i=0;i<=7;i++)
  num[i]=0;

 while(1)
  {
   P1=0x0f;
   key=KEYZHI();
   DF();
   switch(key)
   {
     case 10 : l=0;TR0=1;flag_2=0;break;
     case 11 : l=1;TR0=1;flag_2=0;break;
     case 12 : if(flag_2==1){TR0=1;flag_2=0;}
               else {z0=0;z1=0;TR0=0;flag_2=1;}
               break;
     case 13 : num[0]=0;num[1]=0;num[2]=0;num[3]=0;break;
     case 14 : EX1=1;TR0=1;flag_2=0;break;
     case 15 : time=time_1/20;
               num[0]=(time/60)/10;
	       num[1]=(time/60)%10;
	       num[2]=(time%60)/10;
	       num[3]=(time%60)%10;
	       break;
     default : for(i=0;i<3;i++)
               { j=i+1;  num[i]=num[j]; }
               num[3]=key;  break;        //前4个数码管显示设置的速度值//
   }

   v=100*num[0]+10*num[1]+num[2]+0.1*num[3];
   t=226.7*v+11400;
//   rps_int=10*rps;
//   num[7]=rps_int%10;
//   num[6]=(rps_int/10)%10;
//   num[5]=(rps_int/100)%10;
//   num[4]=(rps_int/1000)%10;
//   dv=v-rps;
//   t=t+114*dv;
  }
}

⌨️ 快捷键说明

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