mc_control.c

Go to the documentation of this file.
00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
00013 
00014 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
00015  *
00016  * Redistribution and use in source and binary forms, with or without
00017  * modification, are permitted provided that the following conditions are met:
00018  *
00019  * 1. Redistributions of source code must retain the above copyright notice,
00020  * this list of conditions and the following disclaimer.
00021  *
00022  * 2. Redistributions in binary form must reproduce the above copyright notice,
00023  * this list of conditions and the following disclaimer in the documentation
00024  * and/or other materials provided with the distribution.
00025  *
00026  * 3. The name of ATMEL may not be used to endorse or promote products derived
00027  * from this software without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
00030  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00031  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
00032  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
00033  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00034  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00035  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00036  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00037  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00038  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039  */
00040 
00041 //_____  I N C L U D E S ___________________________________________________
00042 
00043 #include "mc_control.h"
00044 #include "mc_drv.h"
00045 //_____ M A C R O S ________________________________________________________
00046 
00047 //_____ D E F I N I T I O N S ______________________________________________
00048 
00049 //_____ D E C L A R A T I O N S ____________________________________________
00050 
00051 //Table of current measurement patterns for forward driving.
00052 #ifdef __ICCAVR__
00053 extern code U8
00054 #elif __GNUC__
00055 extern U8
00056 #endif
00057 //CW
00058   ADMUXTableForward[6];
00059 
00060 //Table of current measurement patterns for reverse driving.
00061 #ifdef __ICCAVR__
00062 extern code U8
00063 #elif __GNUC__
00064 extern U8
00065 #endif
00066 //CCW
00067   ADMUXTableReverse[6];
00068 
00069 //Table of output patterns for forward driving.
00070 #ifdef __ICCAVR__
00071 extern code U8
00072 #elif __GNUC__
00073 extern U8
00074 #endif
00075 //CW
00076  commTableForward[6];
00077 
00078 
00079 //Table of output patterns for reverse driving.
00080 #ifdef __ICCAVR__
00081 extern code U8
00082 #elif __GNUC__
00083 extern U8
00084 #endif
00085 //CCW
00086  commTableReverse[6];
00087 
00088 //Edge Level ZC for forward driving.
00089 #ifdef __ICCAVR__
00090 extern code U8
00091 #elif __GNUC__
00092 extern U8
00093 #endif
00094 //CW
00095  zcTableForward[6];
00096 
00097 
00098 //Edge Level ZC for reverse driving.
00099 #ifdef __ICCAVR__
00100 extern code U8
00101 #elif __GNUC__
00102 extern U8
00103 #endif
00104 //CCW
00105  zcTableReverse[6];
00106  
00107 extern volatile U8 nextCommutationStep;
00108 extern volatile U16 speedReferenceADC;
00109 extern volatile U8 speedUpdated;
00110 extern volatile U8 zcPolarity;
00111 
00112 
00114 #define STARTUP_NUM_COMMUTATIONS  29
00115 
00116 #ifdef __ICCAVR__
00117 code U32
00118 #elif __GNUC__
00119 U32
00120 #endif
00121 start_delay[STARTUP_NUM_COMMUTATIONS+1] = 
00122 {2000,1900,1800,1600,1400,1200,1000,800,600,550,500,480,460,440,420,400,380,360,355,350,345,340,335,330,325,320,315,310,305,300};
00123 
00126 void delay_us(volatile long delay)
00127 {
00128   for (volatile long i=0;i<delay;i++);  
00129 }
00130 
00133 void mc_set_duty_cycle(U16 duty)
00134 {
00135   TC1_WRITE_10_BIT_REGISTER(OCR1A, duty);
00136 }
00137 
00143 void mc_start_motor()
00144 {
00145   U8 i = 0;
00146   U8 j = 0;
00147   U8 end_of_start = 0;
00148   mc_set_duty_cycle(STARTUP_PWM_COMPARE_VALUE) ;
00149   
00150   nextCommutationStep = 0;
00151 
00152   while(end_of_start!=1)
00153   {
00154     switch(nextCommutationStep)
00155     {
00156       case 0:       
00157 #if (DIRECTION_OF_ROTATION == CCW) 
00158         TCCR1E = commTableReverse[0];
00159 #else
00160         TCCR1E = commTableForward[0];
00161 #endif        
00162         if (i < 2) i += 1; 
00163         if ((i == 2)&&(j<STARTUP_NUM_COMMUTATIONS)) { 
00164            j += 1;i=0;
00165         }
00166        if ((i==2)&&(j==STARTUP_NUM_COMMUTATIONS)){
00167           end_of_start = 1;
00168         } 
00169         delay_us(start_delay[j]);  
00170         nextCommutationStep = 1;
00171         break;
00172       case 1: 
00173 #if (DIRECTION_OF_ROTATION == CCW)      
00174         TCCR1E = commTableReverse[1];
00175 #else
00176         TCCR1E = commTableForward[1];
00177 #endif
00178         delay_us(start_delay[j]);  
00179         nextCommutationStep = 2;            
00180         break;
00181       case 2:   
00182 #if (DIRECTION_OF_ROTATION == CCW)      
00183         TCCR1E = commTableReverse[2];
00184 #else
00185         TCCR1E = commTableForward[2];
00186 #endif        
00187         delay_us(start_delay[j]);  
00188         nextCommutationStep = 3;
00189         break;
00190       case 3:
00191 #if (DIRECTION_OF_ROTATION == CCW)      
00192         TCCR1E = commTableReverse[3];
00193 #else
00194         TCCR1E = commTableForward[3];
00195 #endif        
00196         delay_us(start_delay[j]);  
00197         nextCommutationStep = 4;           
00198         break;
00199       case 4:       
00200 #if (DIRECTION_OF_ROTATION == CCW)      
00201         TCCR1E = commTableReverse[4];
00202 #else
00203         TCCR1E = commTableForward[4];
00204 #endif        
00205         delay_us(start_delay[j]);  
00206         nextCommutationStep = 5;          
00207         break;
00208       case 5:  
00209 #if (DIRECTION_OF_ROTATION == CCW)      
00210         TCCR1E = commTableReverse[5];
00211 #else
00212         TCCR1E = commTableForward[5];
00213 #endif        
00214         delay_us(start_delay[j]);  
00215         nextCommutationStep = 0;            
00216         break;
00217     default :
00218       nextCommutationStep = nextCommutationStep;
00219       break;
00220     }
00221   }
00222 
00223   //nextCommutationStep++;
00224   nextCommutationStep = 0;
00225   // Use LSB of nextCommutationStep to determine zero crossing polarity.  
00226 #if (DIRECTION_OF_ROTATION == CCW)  
00227   zcPolarity = zcTableReverse[nextCommutationStep];
00228   ADMUX = ADMUXTableReverse[nextCommutationStep];
00229 #else
00230   zcPolarity = zcTableForward[nextCommutationStep];
00231   ADMUX = ADMUXTableForward[nextCommutationStep];
00232 #endif 
00233   // Switch to sensorless commutation.
00234   TC0_WRITE_TCNT0(0);
00235 
00236   // Enable Timer 1 Interrupt
00237   SET_TIMER1_INT_ZC_DETECTION;
00238 
00239 }
00240 
00243 void mc_regulation_loop()
00244 {
00245   // Only update duty cycle if a new speed reference measurement has been made. (Done right after speed measurement is ready)
00246   if (speedUpdated)
00247   {
00248     speedUpdated = FALSE;
00249     // Calculate duty cycle from speed reference value.
00250     mc_set_duty_cycle(MIN_PWM_COMPARE_VALUE+(speedReferenceADC>>3));
00251   }
00252 }
00253 
00254 

Generated on Mon Dec 1 11:12:20 2008 for AVR498 : Atmel BLDC control on ATAVRMC301 with ATtiny861 by  doxygen 1.5.4