sensor_three_phase_BLDC.c File Reference


Detailed Description

A brief description of the file is written here.

A more detailed description of the file should written here.

Application note:
AVR443: Sensorbased control of three-phase BLDC motor
For comprehensive code documentation, supported compilers, compiler settings and supported devices see readme.html
Target device: ATmega48/88/168
Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@atmel.com
$Name$
Revision
2441
$RCSfile$
Date
2007-09-18 07:56:18 +0200 (ti, 18 sep 2007)

Definition in file sensor_three_phase_BLDC.c.

#include <ioavr.h>
#include <inavr.h>
#include "sensor_three_phase_BLDC.h"

Include dependency graph for sensor_three_phase_BLDC.c:

Go to the source code of this file.

Data Structures

union  _fastTemp
 Used for optimized temporary varables. More...

Functions

unsigned char Get_ADC8 (unsigned char muxSetting)
 Start an AD convertion and return result.
static void Init_ADC (void)
 Initialize ADC module.
static void Init_MC_pin_change_interrupt (void)
 Initialize pin change interrupts for PORTB pin 1, 2 and 3.
static void Init_MC_timers (void)
 Initialize motor control timers.
void main (void)
 Main function for motor control example.
__interrupt void PCINT0_ISR (void)
static void Set_Direction (unsigned char direction)
 Set motor direction, CW og CCW.
static void Set_Speed (unsigned char speed)
 Set motor speed.

Variables

__regvar __no_init unsigned
char 
count
 Optimized variable decremented every pin change int.
unsigned char drvPatternsCCW []
 CCW rotation patterns.
unsigned char drvPatternsCW []
 CW rotation patterns.
__regvar __no_init union _fastTemp fastTemp
 Used for optimized temporary varables.
__regvar __no_init unsigned
char 
hallMask
 Workaround for internal compiler error.
__regvar __no_init unsigned
char * 
pDrvPattern
 Stores the current motor driver pattern.


Function Documentation

unsigned char Get_ADC8 ( unsigned char  muxSetting  ) 

Start an AD convertion and return result.

Starts an AD conversion on the specified ADC channel and returns the result when the conversin is completed. Uses polling to wait for the AD conversion to complete.

Parameters:
channel Specify the ADMUX register settings to access the correct channel.
Returns:
adcResult 8-bit result (high byte of AD convertion).

Definition at line 176 of file sensor_three_phase_BLDC.c.

Referenced by main().

00177 {
00178     ADMUX = muxSetting;
00179     // Start AD conversion.
00180     ADCSRA |= (1 << ADSC);
00181     // Wait for ADC conversion to complete.
00182     while ( ADCSRA & (1 << ADSC) );
00183     return ADCH;
00184 }

static void Init_ADC ( void   )  [static]

Initialize ADC module.

Sets up the ADC with prescaler value 4, which means a maximum sample speed of CPU frequency divided by 52 (13*4). With the ADC measuring the speed set point and shunt voltage, this gives a reaction time of two samples for detecting over-current.

Parameters:
void 
Returns:
void

Definition at line 238 of file sensor_three_phase_BLDC.c.

Referenced by main().

00239 {
00240   ADCSRA = (1 << ADEN) | (1 << ADPS1); // Enable ADC, clock prescaler = 4
00241 }

static void Init_MC_pin_change_interrupt ( void   )  [static]

Initialize pin change interrupts for PORTB pin 1, 2 and 3.

Sets up the pins used to sense the Hall sensor signals to generate interrupt if the pin level changes (both rising and falling edge).

Parameters:
void 
Returns:
void

Definition at line 158 of file sensor_three_phase_BLDC.c.

Referenced by main().

00159 {
00160   PCMSK0 = (1<<PCINT1)|(1<<PCINT2)|(1<<PCINT3); //Enable pin change interrupt on PB1:3
00161   PCICR = 1<<PCIE0;    // Enable pin change interrupt0 (PORTB)
00162 }

static void Init_MC_timers ( void   )  [static]

Initialize motor control timers.

Initialize the Timer 1 and timer 2 to run in phase and frequency correct PWM mode (symmetric PWM). The base frequency is set to 32kHz (can be reduced at the expense of lower resolution on the speed control). The functions also ensures that the timers are counting in synch.

Parameters:
void 
Returns:
void

Definition at line 199 of file sensor_three_phase_BLDC.c.

Referenced by main().

00200 {
00201   //Timer Counter 0. OCRA and OCRB used for motor
00202   TCCR0A = (1<<COM0A1)|(0<<COM0A0)|        // Clear OCRA on compare match
00203            (1<<COM0B1)|(0<<COM0B0)|        // Clear OCRB on compare match
00204            (1<<WGM01)|(1<<WGM00);         // Fast PWM mode
00205   TCCR0B = (0<<FOC0A)|(0<<FOC0B)|
00206            (0<<WGM02)|                     // Fast PWM mode
00207            (0<<CS02)|(0<<CS01)|(1<<CS00); // Prescaler = CLK/1
00208 
00209   //Timer Counter 2. OCRA and OCRB used for motor
00210   TCCR2A = (0<<COM2A1)|(0<<COM2A0)|        // OCRA not connected
00211            (1<<COM2B1)|(0<<COM2B0)|        // Clear OCRB on compare match
00212            (1<<WGM01)|(1<<WGM00);         // Fast PWM mode
00213   TCCR2B = (0<<FOC2A)|(0<<FOC2B)|
00214            (0<<WGM22)|                     // Fast PWM mode
00215            (0<<CS22)|(0<<CS21)|(1<<CS20); // Prescaler = CLK/1
00216 
00217   // Synchronize timers
00218   TCNT0 = 0;
00219   TCNT2 = 3;
00220 
00221   TIFR0 = TIFR0;    // Clear TC0 interrupt flags
00222   TIFR1 = TIFR1;    // Clear TC2 interrupt flags
00223 }

void main ( void   ) 

Main function for motor control example.

Initialize speed variables to zero speed, and enabled operation in clockwise direction. Hence a speed reference input is read from ADC_MUX_SPEED_REF. If Current exeeds the MAX_CURRENT_ADC limit the speed (PWM duty cycle) is reduced.

Parameters:
void 
Returns:
void

Definition at line 308 of file sensor_three_phase_BLDC.c.

References ADC_MUX_SHUNT_H, ADC_MUX_SPEED_REF, CLOCKWISE, DDR_HALL, DDR_MC, Get_ADC8(), HALL_MASK, hallMask, Init_ADC(), Init_MC_pin_change_interrupt(), Init_MC_timers(), MAX_CURRENT_ADC, MC_MASK, OVERCURRENT_PIN, PORT_HALL, Set_Direction(), and Set_Speed().

00309 {
00310   unsigned char speed = 0;
00311   unsigned char setspeed = 0;
00312   signed int current;
00313   MCUCR |= (1<<PUD);  // Disable all pull-ups
00314   hallMask = HALL_MASK; // Initialize hallMask variable
00315   //Set initial direction.
00316   Set_Direction( CLOCKWISE );
00317 
00318   Init_MC_timers();
00319   Init_MC_pin_change_interrupt();
00320   Init_ADC();
00321 
00322   DDR_HALL |= HALL_MASK;    //Lock HALL sensor by driving Hall lines
00323   PORT_HALL |= HALL_MASK;
00324   PORT_HALL &= ~HALL_MASK;  //Release HALL sensor lines and trigger PC interrupt
00325   DDR_HALL &= ~HALL_MASK;
00326   __enable_interrupt();
00327   Set_Speed(speed);
00328   DDR_MC = MC_MASK;        // Enable outputs
00329 
00330   DDRC |= (1<<PC1);
00331   for(;;) {
00332     // Get shunt voltage (current measurement)
00333     current = Get_ADC8(ADC_MUX_SHUNT_H);
00334     // If current consumption is too high, limit current
00335     if (current > MAX_CURRENT_ADC )
00336     {
00337       PORTC &= ~(1<<OVERCURRENT_PIN);   //Turn on over-current LED (active low)
00338       if( speed >= 2 )
00339       {
00340         speed -= 2; // Slow down if too fast.
00341       }
00342     }
00343     else
00344     {
00345       PORTC |= (1<<OVERCURRENT_PIN); // Turn off over-current LED (active low)
00346       // Get speed reference voltage (Assumes 2.5V to be maximum analog input,
00347       // multiplied by 2 to convert to PWM range).
00348       setspeed = Get_ADC8(ADC_MUX_SPEED_REF)*2;
00349       // Approach speed set point.
00350       if( setspeed > speed )
00351       {
00352         ++speed;
00353       }
00354       else
00355       {
00356         if( setspeed < speed )
00357         {
00358           --speed;
00359         }
00360       }
00361     }
00362 
00363     Set_Speed(speed);
00364   }
00365 }

Here is the call graph for this function:

__interrupt void PCINT0_ISR ( void   ) 

Updates the PWM outputs controlling the low side of the driver and the IO controlling the high side of the driver. To ensure a speed optimal interrupt the variables used in the interrupt are placed in reserved registers (locked for this purpose only). Further, the information required to do the commutation is placed in tables that are accessed very efficiently using the Hall sensor input signals as offset.

Parameters:
void 
Returns:
void

Definition at line 129 of file sensor_three_phase_BLDC.c.

References count, fastTemp, hallMask, PATTERN_COM0_OFFSET, PATTERN_COM2_OFFSET, pDrvPattern, PIN_HALL, PORT_MC, and _fastTemp::word.

00130 {
00131   unsigned char *pTemp;
00132   fastTemp.word = ((PIN_HALL & hallMask)>>1);  // Read Hall, Mask Pins, shift to use as pointer offset
00133 //  Line below is desirable performance wise, but causes an internal error in compiler
00134 //  fastTemp.LByte = (PIN_HALL & HALL_MASK)>>1;   // Read Hall, Mask Pins, shift to use as pointer offset
00135 
00136   pTemp = pDrvPattern + fastTemp.word;
00137 //  TCCR0A = fastTemp.HByte; //Disable PWM outputs (and thereby close low side FET)
00138 //  TCCR2A = fastTemp.HByte; //Disable PWM output (and thereby close low side FET)
00139 
00140   PORT_MC = *(pTemp);    //Change drive levels on high side
00141 
00142   TCCR0A = *(pTemp + PATTERN_COM0_OFFSET);    // Reconfigure output compare operation for T0
00143   TCCR2A = *(pTemp + PATTERN_COM2_OFFSET); // Reconfigure output compare operation for T2
00144   count--;
00145 }

static void Set_Direction ( unsigned char  direction  )  [static]

Set motor direction, CW og CCW.

Set the commutation table pointer up to point at either the clockwise or counter clockwise direction table. Note that it is not recommended to change direction without first reducing the speed of the motor, preferably stopping it fully.

Parameters:
direction Direction is given as Clockwise or Counter Clockwise.
Returns:
void

Definition at line 281 of file sensor_three_phase_BLDC.c.

References CLOCKWISE, drvPatternsCCW, drvPatternsCW, and pDrvPattern.

Referenced by main().

00282 {
00283   if(direction == CLOCKWISE)
00284   {
00285     __disable_interrupt();        //Variable also used in interrupt and access most be protected
00286     pDrvPattern = drvPatternsCW;   // Set dir to CW, by pointing to CW pattern
00287     __enable_interrupt();
00288   }
00289   else
00290   {
00291     __disable_interrupt();        //Variable also used in interrupt and access most be protected
00292     pDrvPattern = drvPatternsCCW;   // Set dir to CCW, by pointing to CCW pattern
00293     __enable_interrupt();
00294   }
00295 }

static void Set_Speed ( unsigned char  speed  )  [static]

Set motor speed.

Updates the output compare registers of the timer 0 and timer 2 which control the duty cycle of the PWM output and thereby the speed of the motor. The method used ensures that that all PWM channels are behaving same duty cycle.

Parameters:
speed Compare match value that defines PWM duty cycle.
Returns:
void

Definition at line 256 of file sensor_three_phase_BLDC.c.

Referenced by main().

00257 {
00258   TIFR0 = TIFR0;    // Clear TC0 interrupt flags
00259   while( !(TIFR0 & (1<<TOV0)));  // Wait for TOV to ensure that all registers are
00260                             //  updated in the same timer cycle
00261   __disable_interrupt();
00262   OCR0A = speed;        // Change the duty cycle
00263   OCR0B = speed;
00264   OCR2B = speed;
00265   __enable_interrupt();
00266 }


Variable Documentation

__regvar __no_init unsigned char count

Optimized variable decremented every pin change int.

Definition at line 109 of file sensor_three_phase_BLDC.c.

Referenced by PCINT0_ISR().

unsigned char drvPatternsCCW[]

Initial value:

CCW rotation patterns.

Configuration of pin drive levels and timer COM bits in different phases for CounterClockWise rotation.

Definition at line 33 of file sensor_three_phase_BLDC.c.

Referenced by Set_Direction().

unsigned char drvPatternsCW[]

Initial value:

CW rotation patterns.

Configuration of pin drive levels and timer COM bits in different phases for ClockWise rotation.

Definition at line 66 of file sensor_three_phase_BLDC.c.

Referenced by Set_Direction().

__regvar __no_init union _fastTemp fastTemp

Used for optimized temporary varables.

Referenced by PCINT0_ISR().

__regvar __no_init unsigned char hallMask

Workaround for internal compiler error.

Definition at line 108 of file sensor_three_phase_BLDC.c.

Referenced by main(), and PCINT0_ISR().

__regvar __no_init unsigned char* pDrvPattern

Stores the current motor driver pattern.

Definition at line 94 of file sensor_three_phase_BLDC.c.

Referenced by PCINT0_ISR(), and Set_Direction().


Generated on Tue Sep 18 08:53:13 2007 for AVR443 Sensor-based control of three phase Brushless DC Motor by  doxygen 1.4.7