mc_drv.c

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 //_____  I N C L U D E S ___________________________________________________
00012 
00013 #ifdef __ICCAVR__ // IAR C Compiler
00014 #include "config.h"
00015 #include "lib_mcu/compiler.h"
00016 #include "lib_mcu/mcu.h"
00017 #include "inavr.h"
00018 #include <stdio.h>
00019 #endif
00020 
00021 #ifdef __GNUC__  // GNU C Compiler
00022 #include "config_for_gcc.h"
00023 #include <avr/io.h>
00024 #include <avr/interrupt.h>
00025 #include "mc_interface.h"
00026 #endif
00027 
00028 
00029 
00030 #include "table_sin81.h"
00031 #include "lib_mcu/pll/pll_drv.h"
00032 
00033 
00034 //_____ M A C R O S ________________________________________________________
00035 /* definition of Hall sectors MC200 */
00036 /*#define HAS1     (1<<PIND7) | (0<<PINB2) | (1<<PIND6)
00037 #define HAS2     (0<<PIND7) | (0<<PINB2) | (1<<PIND6)
00038 #define HAS3     (0<<PIND7) | (1<<PINB2) | (1<<PIND6)
00039 #define HAS4     (0<<PIND7) | (1<<PINB2) | (0<<PIND6)
00040 #define HAS5     (1<<PIND7) | (1<<PINB2) | (0<<PIND6)
00041 #define HAS6     (1<<PIND7) | (0<<PINB2) | (0<<PIND6)*/
00042 
00043 /* definition of Hall sectors MC100 */
00044 /* be careful this definition is one sector in advance */
00045 /*                Hall_C      Hall_B        Hall_A     */
00046 #define HAS1     (1<<PIND5) | (0<<PINC6) | (1<<PIND7)
00047 #define HAS2     (0<<PIND5) | (0<<PINC6) | (1<<PIND7)
00048 #define HAS3     (0<<PIND5) | (1<<PINC6) | (1<<PIND7)
00049 #define HAS4     (0<<PIND5) | (1<<PINC6) | (0<<PIND7)
00050 #define HAS5     (1<<PIND5) | (1<<PINC6) | (0<<PIND7)
00051 #define HAS6     (1<<PIND5) | (0<<PINC6) | (0<<PIND7)
00052 
00053 //_____ D E F I N I T I O N S ______________________________________________
00054 
00055 void   init(void);
00056 void   PSC_Init(unsigned int ot0,  unsigned int ot1);
00057 void   PSC_Load (unsigned int dt0a,  unsigned int dt1a,
00058                  unsigned int dt0b,  unsigned int dt1b,
00059                  unsigned int dt0c,  unsigned int dt1c);
00060 U16    mc_control_speed_16b(U16 speed_ref , U16 speed_measure);
00061 void   SVPWM(U16 amp, U8 Counter_Value, U8 Top, U8 Sector);
00062 S16    read_acquisition() ;
00063 void   PSC_Start(void);
00064 void   PSC_Stop(void);
00065 void   Do_Sensor_Interrupt(void);
00066 void   Start_ADC(void);
00067 
00068 //_____ D E C L A R A T I O N S ____________________________________________
00069 volatile U8   Hall_Sector = HAS1 ;     
00070 volatile U8   Mem_Hall_Sector = HAS1 ; 
00071 volatile U8   Sensor_Counter_Up = 0;   
00072 volatile U8   Sensor_Counter_Down = 1; 
00073 volatile U8   Top_Counter = 1;         
00074 volatile U8   Mem_Top_Counter = 1;     
00075 volatile U16  Mem_Top_CounterX8 = 1;   
00076 volatile U8   Delay_For_Change = 1;    
00077 
00078 volatile U8   Prescaler_Main_Tick;     
00079 
00080 volatile U16  Amplitude = 0;           
00081 volatile U16  PWM0, PWM1, PWM2;        
00082 volatile U16  Measured_Speed;          
00083 
00084 volatile U16  Permanent_Clock = 0;
00085 volatile U8   Hall_Event_Count = 8;    
00086 volatile U16  Mem_Hall_Time = 0;       
00087 volatile U16  Hall_Period = 65535;     
00088 
00089 extern volatile Bool mci_run_stop;     
00090 extern volatile U8   Main_Tick;        
00091 extern Bool mci_direction;
00092 
00093 
00103 void PSC_Init(unsigned int ot0,  unsigned int ot1)
00104 {
00105    Start_pll_64_mega();   // start the PLL at 64 MHz
00106    Wait_pll_ready();
00107 
00108    OCR0RAH = HIGH(ot0);
00109    OCR0RAL = LOW(ot0);
00110    OCR0RBH = HIGH(ot1);
00111    OCR0RBL = LOW(ot1);
00112    PCNF0 = (1<<PMODE01) | (1<<PMODE00) | (1<<POP0) | (1<<PCLKSEL0) ;  /* fast clock input used */
00113    PFRC0A = 0;
00114 //   PFRC0A = (1<<PFLTE0A)|(0<<PRFM0A3)|(1<<PRFM0A2)|(1<<PRFM0A1)|(1<<PRFM0A0); /* overcurrent */
00115    PFRC0B = 0;
00116    PCTL0 = (1<<PARUN0) | (1<<PCCYC0);
00117 
00118    OCR1RAH = HIGH(ot0);
00119    OCR1RAL = LOW(ot0);
00120    OCR1RBH = HIGH(ot1);
00121    OCR1RBL =  LOW(ot1);
00122    PCNF1 = (1<<PMODE11) | (1<<PMODE10) | (1<<POP1) | (1<<PCLKSEL1);   /* fast clock input used */
00123    PFRC1A = 0;
00124    PFRC1B = 0;
00125    PCTL1 = (1<<PARUN1) | (1<<PCCYC1);
00126 
00127    OCR2RAH = HIGH(ot0);
00128    OCR2RAL = LOW(ot0);
00129    OCR2RBH = HIGH(ot1);
00130    OCR2RBL = LOW(ot1);
00131    PCNF2 = (1<<PMODE21) | (1<<PMODE20) | (1<<POP2) | (1<<PCLKSEL2);   /* fast clock input used */
00132    PFRC2A = 0;
00133    PFRC2B = 0;
00134 //   PCTL2 = (1<<PCCYC2) | (1<<PRUN2) ;
00135 
00136    // connect the PSC waveform generator outputs to the port outputs
00137    PSOC0 = (1<<POEN0B) | (1<<POEN0A) ;
00138    PSOC1 = (1<<POEN1B) | (1<<POEN1A) ;
00139    PSOC2 = (1<<POEN2B) | (1<<POEN2A) ;
00140 
00141 }
00142 
00143 
00150 inline void PSC_Load (unsigned int dt0a,  unsigned int dt1a,
00151                unsigned int dt0b,  unsigned int dt1b,
00152                unsigned int dt0c,  unsigned int dt1c)
00153 {
00154    PCNF0 = (1<<PLOCK0)|(1<<PMODE01) | (1<<PMODE00) | (1<<POP0) | (1<<PCLKSEL0);
00155    PCNF1 = (1<<PLOCK1)|(1<<PMODE11) | (1<<PMODE10) | (1<<POP1) | (1<<PCLKSEL1);
00156    PCNF2 = (1<<PLOCK2)|(1<<PMODE21) | (1<<PMODE20) | (1<<POP2) | (1<<PCLKSEL2);
00157 
00158    OCR0SAH = HIGH(dt0a);
00159    OCR0SAL = LOW(dt0a);
00160    OCR0SBH = HIGH(dt1a);
00161    OCR0SBL = LOW(dt1a);
00162 
00163    OCR1SAH = HIGH(dt0b);
00164    OCR1SAL = LOW(dt0b);
00165    OCR1SBH = HIGH(dt1b);
00166    OCR1SBL = LOW(dt1b);
00167 
00168    OCR2SAH = HIGH(dt0c);
00169    OCR2SAL = LOW(dt0c);
00170    OCR2SBH = HIGH(dt1c);
00171    OCR2SBL = LOW(dt1c);
00172 
00173    PCNF0 = (1<<PMODE01) | (1<<PMODE00) | (1<<POP0) | (1<<PCLKSEL0);
00174    PCNF1 = (1<<PMODE11) | (1<<PMODE10) | (1<<POP1) | (1<<PCLKSEL1);
00175    PCNF2 = (1<<PMODE21) | (1<<PMODE20) | (1<<POP2) | (1<<PCLKSEL2);
00176 }
00177 
00184 void PSC_Start(void)
00185 {
00186    PCTL2 = (1<<PCCYC2) | (1<<PRUN2) ;
00187 }
00188 
00189 
00196 void PSC_Stop(void)
00197 {
00198    PCTL2 = (1<<PCCYC2);
00199 }
00200 
00201 
00202 
00203 /* ------------------ TIMER 0 - INTERRUPT --------------------*/
00213 // interrupt vector for the sampling period
00214 #ifdef __ICCAVR__ // IAR C Compiler
00215 #pragma vector = TIMER0_COMPA_vect
00216 __interrupt void Timer0_IT(void)
00217 #endif
00218 #ifdef __GNUC__  // GNU C Compiler
00219 ISR(TIMER0_COMPA_vect)
00220 #endif
00221 {
00222    U16    tau1, tau2 ;
00223    U8     theta1 , theta2 ;
00224    U16    Thetai_1;
00225    Set_PC1();
00226 
00227    Permanent_Clock++;
00228 
00229    if (Delay_For_Change != 0)
00230    {
00231 
00232       Delay_For_Change --;
00233       if (Delay_For_Change == 0)
00234       {
00235          /* Change_Sector */
00236          Top_Counter = Mem_Top_Counter;
00237          if (Top_Counter == 0) Top_Counter++; /* to avoid "divide by 0" */
00238          Sensor_Counter_Down = Mem_Top_Counter;
00239          Hall_Sector = Mem_Hall_Sector;
00240          /* end Change_Sector */
00241       }
00242    }
00243 
00244    /* increment Sensor_Counter_Up */
00245    if ( Sensor_Counter_Up < 255 )
00246    {
00247       Sensor_Counter_Up += 1;
00248    }
00249 
00250    /* decrement Sensor_Counter_Down */
00251    if (Sensor_Counter_Down != 0) Sensor_Counter_Down -= 1;
00252 
00253 
00254    // -------------- space vector PWM algorithm -----------------
00255    Thetai_1 = ((U16)(Top_Counter - Sensor_Counter_Down) * MAX_THETA) / Top_Counter;
00256 
00257    Enable_interrupt();
00258 
00259    theta2 = (unsigned char) Thetai_1 ;
00260 
00261    theta1 = (unsigned char) (MAX_THETA - theta2) ;
00262 
00263    /* 128 is the max value of the normalized sin table */
00264    tau1 = ((U32)Amplitude * tab_sin[theta1]) / 128 ;
00265    tau2 = ((U32)Amplitude * tab_sin[theta2]) / 128 ;
00266 
00267    if (mci_direction == CW)
00268    {
00269       switch (Hall_Sector)
00270       {
00271       case HAS5 :
00272          PWM0 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ;
00273          PWM1 = (unsigned short int) (MAX_PWM/2 + tau1 - tau2) ;
00274          PWM2 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ; break ;
00275       case HAS4 :
00276          PWM0 = (unsigned short int) (MAX_PWM/2 - tau1 + tau2) ;
00277          PWM1 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ;
00278          PWM2 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ; break ;
00279       case HAS3 :
00280          PWM0 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ;
00281          PWM1 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ;
00282          PWM2 = (unsigned short int) (MAX_PWM/2 + tau1 - tau2) ; break ;
00283       case HAS2 :
00284          PWM0 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ;
00285          PWM1 = (unsigned short int) (MAX_PWM/2 - tau1 + tau2) ;
00286          PWM2 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ; break ;
00287       case HAS1 :
00288          PWM0 = (unsigned short int) (MAX_PWM/2 + tau1 - tau2) ;
00289          PWM1 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ;
00290          PWM2 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ; break ;
00291       case HAS6 :
00292          PWM0 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ;
00293          PWM1 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ;
00294          PWM2 = (unsigned short int) (MAX_PWM/2 - tau1 + tau2) ; break ;
00295       default :
00296          PWM0 = (unsigned short int) (MAX_PWM/2) ;
00297          PWM1 = (unsigned short int) (MAX_PWM/2) ;
00298          PWM2 = (unsigned short int) (MAX_PWM/2) ; break ;
00299       }
00300       PSC_Load (PWM0, PWM0+DEAD_TIME, PWM2, PWM2+DEAD_TIME, PWM1, PWM1+DEAD_TIME); // CW
00301    }
00302    else
00303    {
00304       switch (Hall_Sector)
00305       {
00306       case HAS1 :
00307          PWM0 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ;
00308          PWM1 = (unsigned short int) (MAX_PWM/2 + tau1 - tau2) ;
00309          PWM2 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ; break ;
00310       case HAS2 :
00311          PWM0 = (unsigned short int) (MAX_PWM/2 - tau1 + tau2) ;
00312          PWM1 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ;
00313          PWM2 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ; break ;
00314       case HAS3 :
00315          PWM0 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ;
00316          PWM1 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ;
00317          PWM2 = (unsigned short int) (MAX_PWM/2 + tau1 - tau2) ; break ;
00318       case HAS4 :
00319          PWM0 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ;
00320          PWM1 = (unsigned short int) (MAX_PWM/2 - tau1 + tau2) ;
00321          PWM2 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ; break ;
00322       case HAS5 :
00323          PWM0 = (unsigned short int) (MAX_PWM/2 + tau1 - tau2) ;
00324          PWM1 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ;
00325          PWM2 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ; break ;
00326       case HAS6 :
00327          PWM0 = (unsigned short int) (MAX_PWM/2 - tau1 - tau2) ;
00328          PWM1 = (unsigned short int) (MAX_PWM/2 + tau1 + tau2) ;
00329          PWM2 = (unsigned short int) (MAX_PWM/2 - tau1 + tau2) ; break ;
00330       default :
00331          PWM0 = (unsigned short int) (MAX_PWM/2) ;
00332          PWM1 = (unsigned short int) (MAX_PWM/2) ;
00333          PWM2 = (unsigned short int) (MAX_PWM/2) ; break ;
00334       }
00335       PSC_Load (PWM0, PWM0+DEAD_TIME, PWM1, PWM1+DEAD_TIME, PWM2, PWM2+DEAD_TIME); // CCW
00336    }
00337 
00338    // -------- generate the main Tick ---------------------------
00339    Prescaler_Main_Tick -= 1;
00340    if (Prescaler_Main_Tick == 0)
00341    {
00342 //      Prescaler_Main_Tick = 21; /* 21 * 48µS generates 1.008mS */
00343 //      Prescaler_Main_Tick = 104; /* 104 * 48µS generates 5mS */
00344       Prescaler_Main_Tick = 78; /* 78 * 64µS generates 5mS */
00345       Main_Tick=1;
00346    }
00347    Clear_PC1();
00348 }
00349 
00350 
00351 
00352 
00353 /* ---------------- SENSOR - INTERRUPT ------------------*/
00356 inline void Do_Sensor_Interrupt(void)
00357 {
00358    if ( Sensor_Counter_Up > 3 )
00359    {
00360 
00361       if (Delay_For_Change != 0)
00362       {
00363          /* Last Delay not finished : Force Change_Sector */
00364          Top_Counter = Mem_Top_Counter;
00365          if (Top_Counter == 0) Top_Counter++; /* to avoid "divide by 0" */
00366 
00367          Sensor_Counter_Down = Mem_Top_Counter;
00368          Hall_Sector = Mem_Hall_Sector;
00369          /* end Change_Sector */
00370       }
00371 
00372       /* Filter and memorize the Conuter_Up in the Top_Counter */
00373       Mem_Top_CounterX8 = (((U16)7 * Mem_Top_CounterX8) + (U16)8 * Sensor_Counter_Up) >>3;
00374       Mem_Top_Counter = Mem_Top_CounterX8 >> 3;
00375 
00376       Sensor_Counter_Up = 0; /* reset the Counter_Up */
00377 
00378       /* Get the status of the 3 Hall sensors */
00379       /* Hall_Sector = PIND7.PIND6.0.0.0.PINB2.0 */
00380 //      Mem_Hall_Sector = ( PIND & ( (1<<PIND7)|(1<<PIND6) ) ) | (PINB & (1<<PINB2)); //MC200
00381       Mem_Hall_Sector = ( PIND & ( (1<<PIND7)|(1<<PIND5) ) ) | (PINC & (1<<PINC6)); //MC100
00382 
00383       /* arm the Delay_For_Change */
00384       Delay_For_Change = Mem_Top_Counter - ADVANCE;
00385 
00386    } /* else false interrupt */
00387 
00388 }
00389 
00390 /* -------------- COMPARATOR 0 - INTERRUPT -----------------*/
00393 #ifdef __ICCAVR__ // IAR C Compiler
00394 #pragma vector = ANACOMP_0_vect
00395 __interrupt void Hall_A(void)
00396 #endif
00397 #ifdef __GNUC__  // GNU C Compiler
00398 ISR(ANALOG_COMP_0_vect)
00399 #endif
00400 {
00401    Do_Sensor_Interrupt();
00402    if (Hall_Event_Count-- == 0)
00403    {
00404       Hall_Event_Count = 7;
00405       if (Permanent_Clock >= Mem_Hall_Time)
00406       {
00407          Hall_Period = Permanent_Clock - Mem_Hall_Time;
00408       }
00409       else
00410       {
00411          Hall_Period = 65535 - Mem_Hall_Time + Permanent_Clock ;
00412       }
00413       Mem_Hall_Time = Permanent_Clock;
00414    }
00415 }
00416 
00417 /* -------------- COMPARATOR 1 - INTERRUPT -----------------*/
00419 #ifdef __ICCAVR__ // IAR C Compiler
00420 #pragma vector = ANACOMP_1_vect
00421 __interrupt void Hall_B(void)
00422 #endif
00423 #ifdef __GNUC__  // GNU C Compiler
00424 ISR(ANALOG_COMP_1_vect)
00425 #endif
00426 {
00427    Do_Sensor_Interrupt();
00428    Start_ADC();
00429 }
00430 
00431 /* -------------- COMPARATOR 2 - INTERRUPT -----------------*/
00433 #ifdef __ICCAVR__ // IAR C Compiler
00434 #pragma vector = ANACOMP_2_vect
00435 __interrupt void Hall_C(void)
00436 #endif
00437 #ifdef __GNUC__  // GNU C Compiler
00438 ISR(ANALOG_COMP_2_vect)
00439 #endif
00440 {
00441    Do_Sensor_Interrupt();
00442 }
00443 
00444 
00446 void svpwm_init(void)
00447 {
00448    Sensor_Counter_Up = 4;
00449    Mem_Top_Counter = 200;
00450    Top_Counter = Mem_Top_Counter+1;
00451    Delay_For_Change = 200;
00452    Hall_Sector = Mem_Hall_Sector ;
00453 }
00454 
00456 U16 get_Hall_Period(void)
00457 {
00458    U16 value_to_return;
00459 
00460    Disable_interrupt();
00461    value_to_return = Hall_Period;
00462    Enable_interrupt();
00463    return value_to_return;
00464 }
00465 
00467 void store_new_amplitude(U16 new_val)
00468 {
00469    Disable_interrupt();
00470    Amplitude = new_val;
00471    Enable_interrupt();
00472 }
00473 

Generated on Tue Sep 16 18:11:19 2008 for Atmel BLDC Sinusoidal on ATAVRMC100 by  doxygen 1.5.3