2011年12月20日 星期二

PWM generation for STEP motor control

//=========================
//Project:     PWM generation for STEP motor control
//Author:      Leo.Tseng
//Date:        2011/12/21
//MCU:         W78E054D
//CRYSTAL:     25Mhz
//Description: Use uart for input/output, set boudrate=9600,
//             Press "a" to increase PWM high duty, Press "d" to
//             decrease PWM high duty.
//             PWM will control 3-wire step motor.
//=========================
#include  <reg52.h>
#include  <stdio.h>
void uart_initinal(int baudrate);
int TIMES=65536;     // 16bit counter 
int FREQ=10400;      // 200HZ = 10400 機械週期
int PWMHIGH=2080;    // 高電位佔20%=10400*0.2=2080個機械週期
int PWMLOW=8320;     // 低電位佔80%=10400*0.8=8320個機械週期
int PERIOD,n_SCAN;
char ch;
sbit SCAN0 = P1^2;
sbit SCAN1 = P1^3;
sbit SCAN2 = P1^4
//------------------------------------------------
//MAIN C function
//------------------------------------------------
void main (void)
{
 uart_initinal(9600);              // 起始 UART 設定,baudrate=9600
 //PWMOUT = 0;
 TMOD = (TMOD & 0xF0) | 0x01;      // 設定 T/C0 Mode
 PERIOD = TIMES-PWMHIGH;
 TH0 = PERIOD/256;
 TL0 = PERIOD%256;
 ET0 = 1;                         // 致能 Timer 0 Interrupts
 TR0 = 1;                         // 啟動 Timer 0 計時
 EA = 1;                          // 全部致能始動
 SCAN0 = 1;
// PWMOUT1 = 1;
// PWMOUT2 = 1;

 printf("按 ""a"" 增加PWM工作週期20%%,按 ""d"" 減少PWM工作週期20%%\n");          // 顯示操作訊息
 //printf("Press ""a"" to increase duty cycle, ""d"" to decrease duty cycle\n"); // 顯示操作訊息
 while (1)
   {
    switch (ch=_getkey())                         
      {
       // 增加高電位20/%
       case 'A':                                   //
       case 'a':if(PWMHIGH==300)                    //
                   PWMHIGH=2080;
                else if(PWMHIGH <= 6240)        
                        PWMHIGH+=2080;                       
                     else if(PWMHIGH >= 8320)
                            PWMHIGH=10100;         // 最高duty cycle限制97%
               
                PWMLOW=FREQ-PWMHIGH;
                //printf("a_PWMHIGH is %u\n",PWMHIGH);
                break;
      
       // 減少高電位20/%
       case 'D':                                   //
       case 'd':if(PWMHIGH==10100)                  //
                  PWMHIGH=8320;
                else if(PWMHIGH >= 4160)
                       PWMHIGH-=2080;                        
                     else if(PWMHIGH <= 2080)
                            PWMHIGH=300;           // 最低duty cycle限制97%
               
                PWMLOW=FREQ-PWMHIGH;
                //printf("d_PWMHIGH is %u\n",PWMHIGH);
                break;
                
       default: break;                
      }
   }
}

//UART副程式使用timer1
void uart_initinal(int baudrate)      
{
 PCON  = 0x00;                                  // PCON: if SMOD=1(b7), Baud Rate is Doubled                         
 SCON  = 0x52;                                  // SCON: mode 1, 8-bit UART, enable rcvr                   
 TMOD  = (TMOD & 0x0f) | 0x20;                  // TMOD: timer 1, mode 2, 8-bit reload; keeps timer0 default.        
TH1   = 256-(25000000/372/baudrate);           // TH1:  reload value for baud @ 25MHz, TH=0xF9
 //TH1= 256-(11059200/384/baudrate);  
 TR1   = 1;                                     // TR1:  timer 1 run                             
 //TI    = 1;                                   // TI:   set TI to send first char of UART   
}

//計時器0中斷1
void timer0_ISR(void) interrupt 1
{
 if((SCAN0==1)&&(SCAN1==1)&&(SCAN2==1)&&(n_SCAN==0))
  {
   TR0=0;
   PERIOD = TIMES-PWMLOW;                    
   TH0= PERIOD/256;
   TL0= PERIOD%256;
   TR0=1;
   SCAN0=0;
 
  }
 else if((SCAN0==0)&&(SCAN1==1)&&(SCAN2==1)&&(n_SCAN==0))
   {
     TR0=0;
     PERIOD = TIMES-PWMHIGH;                    
     TH0= PERIOD/256;
     TL0= PERIOD%256;
     TR0=1;
     SCAN0=1;
     n_SCAN=1;
    }
   
 if((SCAN1==1)&&(SCAN0==1)&&(SCAN2==1)&&(n_SCAN==1))
  {
   TR0=0;
   PERIOD = TIMES-PWMLOW;                    
   TH0= PERIOD/256;
   TL0= PERIOD%256;
   TR0=1;
   SCAN1=0;
 
  }
 else if((SCAN1==0)&&(SCAN0==1)&&(SCAN2==1)&&(n_SCAN==1))
   {
     TR0=0;
     PERIOD = TIMES-PWMHIGH;                    
     TH0= PERIOD/256;
     TL0= PERIOD%256;
     TR0=1;
     SCAN1=1;
     n_SCAN=2;
    }  
   
 if((SCAN2==1)&&(SCAN0==1)&&(SCAN1==1)&&(n_SCAN==2))
  {
   TR0=0;
   PERIOD = TIMES-PWMLOW;                    
   TH0= PERIOD/256;
   TL0= PERIOD%256;
   TR0=1;
   SCAN2=0;
 
  }
 else if((SCAN2==0)&&(SCAN0==1)&&(SCAN1==1)&&(n_SCAN==2))
   {
     TR0=0;
     PERIOD = TIMES-PWMHIGH;                    
     TH0= PERIOD/256;
     TL0= PERIOD%256;
     TR0=1;
     SCAN2=1;
     n_SCAN=0;
    }       
   
}

===================================================================

沒有留言:

張貼留言