elktro
Üye
- Katılım
- 26 Eki 2008
- Mesajlar
- 18
- Puanları
- 1
- Yaş
- 40
bu program fırcasz dc motor da hız kontrolü aşamalrında ne ler yapılmış komutlr ne işe yaryo bilen varsa paylaşablrmi
Kod:
/***
* *
* Software License Agreement *
* *
* The software supplied herewith by Microchip Technology *
* Incorporated (the "Company") for its dsPIC controller *
* is intended and supplied to you, the Company's customer, *
* for use solely and exclusively on Microchip dsPIC *
* products. The software is owned by the Company and/or its *
* supplier, and is protected under applicable copyright laws. All *
* rights are reserved. Any use in violation of the foregoing *
* restrictions may subject the user to criminal sanctions under *
* applicable laws, as well as to civil liability for the breach of *
* the terms and conditions of this license. *
* *
* THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO *
* WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, *
* BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND *
* FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE *
* COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, *
* INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. *
* *
**********************************************************************/
/**********************************************************************
* *
* Author: Steve Bowling *
* *
* Filename: mc_dev_board.c *
* Date: 11/01/06 *
* File Version: 3.00 *
* *
* Tools used: MPLAB IDE -> 7.43 *
* Compiler -> 2.03 *
* *
* Linker File: p30f6010a.gld *
* *
* *
***********************************************************************
* Code Description
*
* This code demonstrates the features of the dsPIC motor control
* development board and 3-phase power modules.
* The code can be programmed to drive different motor types depending
* on the buttons pressed on the PCB. The following motors are
* supported:
*
* 1. open loop control of AC induction motor using V/Hz algorithm
* 2. open loop control of BLDC motor using hall-effect sensors
* 3. open loop control of brush DC motor.
*
**********************************************************************
Revison History:
Version 2.00:
-------------
-Code modified to include C implementation of SVM() function. SVM
routine now allows full modulation range over previous version.
-Mode selection interface modified to wait for key press at reset.
**********************************************************************/
#include <p30F6010a.h>
#include "hardware.h"
#include "xlcd.h"
#include "svm.h"
/************************Configuration Bits***************************/
_FOSC(CSW_FSCM_OFF & XT_PLL4);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_OFF & MCLR_EN);
_FGS(CODE_PROT_OFF);
/*********************** START OF DEFINITIONS *******************/
// These are the counting periods for the medium and slow speed events.
// Count variables are decremented at each PWM interrupt.
#define SLOW_EVENT_PERIOD 1600 // 100msec period for 16KHz PWM
#define MEDIUM_EVENT_PERIOD 72 // 5msec period for 16KHz PWM
//----------------------------------------------------------------------
// Constants required by ACIM software
//----------------------------------------------------------------------
// These are the definitions used to derive the maximum modulation
// frequency.
// First, specify the max modulation frequency that you want.
#define MAX_MOD_FREQ 60
// Next, specify the frequency of the PWM carrier
#define PWM_MOD_FREQ 16000
// Finally, specify the resolution of the modulation phase angle.
// This is how many counts it takes to complete one modulation
// electrical cycle.
#define MOD_ANGLE_RES 65536
// Now, compute the modulation frequency limit value. This
// constant will be used to limit the speed demand variable.
#define MOD_FREQ_LIMIT (MAX_MOD_FREQ*MOD_ANGLE_RES)/PWM_MOD_FREQ
// These constants define the slope of the Volts-Hertz profile
// and the lower and upper modulation index shelves.
#define V_HZ_SLOPE 200
#define LOW_AMPLITUDE_LIMIT 2000
#define HIGH_AMPLITUDE_LIMIT 32000
#define AMPLITUDE_POT_LIMIT HIGH_AMPLITUDE_LIMIT/V_HZ_SLOPE
//----------------------------------------------------------------------
// Constants required by BLDC motor software
//----------------------------------------------------------------------
// The following definitions are the values that will be written to
// the OVDCON register to acheive the various BLDC commutation states.
// The commutation state is determined by reading the value of the
// hall effect sensors on the motor.
// States 0 and 7 are invalid states and therefore all PWM outputs
// are disabled.
// For soft
// switching, the top device is modulated, while the bottom device
// is always on.
#define STATE0 0x0000
#define STATE1 0x0210
#define STATE2 0x2004
#define STATE3 0x0204
#define STATE4 0x0801
#define STATE5 0x0810
#define STATE6 0x2001
#define STATE7 0x0000
#define BLDC_SPEED_LIMIT 900
//----------------------------------------------------------------------
// Constants required by DC motor software
//----------------------------------------------------------------------
#define BDC_SPEED_LIMIT 400
//----------------------------------------------------------------------
// Software flags
//----------------------------------------------------------------------
// This bit structure provides status flags for the software
volatile struct {
unsigned :1;
unsigned Reverse:1;
unsigned Button1:1;
unsigned Button2:1;
unsigned Button3:1;
unsigned Button4:1;
unsigned DirChange:1;
unsigned Accelerate:1;
unsigned PWMFault:1;
unsigned Restart:1;
unsigned :1;
unsigned :1;
unsigned :1;
unsigned PWMEvent:1;
unsigned MediumEvent:1;
unsigned SlowEvent:1;
} Flags;
// This bit structure provides mode flags for the software
volatile struct {
unsigned ACIMTest:1;
unsigned ACIM:1;
unsigned BLDC:1;
unsigned BDC:1;
unsigned :1;
unsigned :1;
unsigned :1;
unsigned :1;
unsigned :1;
unsigned :1;
unsigned :1;
unsigned :1;
unsigned :1;
unsigned :1;
unsigned :1;
unsigned :1;
} Mode;
//----------------------------------------------------------------------
// System variables
//----------------------------------------------------------------------
// This is a software counter used to time slower system events, such as
// button polling, etc.
unsigned int SlowEventCount, MediumEventCount;
// This variable is used as a software counter to turn the voltage boost
// circuit switch on and off.
unsigned int BoostCount;
// This variable holds the A/D potentiometer reading that controls speed.
unsigned int Speed, OldSpeed;
unsigned int temp;
//----------------------------------------------------------------------
// Variables required by ACIM software
//----------------------------------------------------------------------
// This variable holds the V/Hz slope for the ACIM profile.
unsigned int V_Hz_Slope;
// Phase and Amplitude are the two input variables to the PWM modulation
// function.
unsigned int Amplitude, Phase;
//----------------------------------------------------------------------
// Variables required for BLDC code
//----------------------------------------------------------------------
// This array holds the commutation states for the OVDCON register.
unsigned int BLDCstates[] = {STATE0, STATE1, STATE2, STATE3, STATE4, STATE5, STATE6, STATE7};
// The hall effect sensor states are read from the I/O port and stored
// in HallState. HallState is used as an index to the BLDCstates
// array.
unsigned char HallState;
//----------------------------------------------------------------------
// System functions
//----------------------------------------------------------------------
void Setup(void); // Initializes dsPIC and peripherals
int ReadADC(unsigned int channel);
void __attribute__((__interrupt__)) _PWMInterrupt(void);
void Delay(unsigned int count);
//----------------------------------------------------------------------
// Functions required by ACIM software
//----------------------------------------------------------------------
void Modulate(int volts, unsigned int angle);
//----------------------------------------------------------------------
// Code functions
//----------------------------------------------------------------------
main ( void )
{
Setup();
while(1)
{
ClrWdt(); // Clear the watchdog timer
// This code is executed after each PWM interrupt occurs.
// The PWM ISR sets PWMflag to signal the interrupt.
if(Flags.PWMEvent)
{
// Run this code if driving an AC motor
if(Mode.ACIM || Mode.ACIMTest)
{
// The Speed variable is added or subtracted from the Phase
// variable to control the modulation frequency.
if(Flags.Reverse) Phase -= Speed;
else Phase += Speed;
// Write the duty cycles to the PWM module by calling the SVM
// routine.
SVM(Amplitude,Phase);
}
// Run this code if driving a BLDC motor
if(Mode.BLDC)
{
if(!Flags.PWMFault)
{
// Read the hall effect sensors on PORTD
HallState = (unsigned char)(PORTD >> 8) & 0x07;
// Update the PWM override register with the appropriate commutation
// state.
if(Flags.Reverse)
OVDCON = BLDCstates[7 - HallState];
else
OVDCON = BLDCstates[HallState];
}
}
// Run this code if driving a brush DC motor
if(Mode.BDC)
{
}
// Clear the WDT in the PWM event loop
ClrWdt();
Flags.PWMEvent = 0;
} // end if(PWMEvent)
//-----------------------------------------------------------------
// Medium speed event handler executes every 5msec
//-----------------------------------------------------------------
if(Flags.MediumEvent)
{
// This is the 'motion profile'. If a direction change is
// requested, this code will ramp down the speed setting,
// reverse the motor, then slowly ramp it back up.
if(Flags.DirChange)
{
if(Flags.Accelerate)
{
// If we're not back to original speed, then accelerate
if(Speed != OldSpeed) Speed++;
// If back at original speed, clear the DirChange flag and turn off LED
else
{
Flags.DirChange = 0;
LED4 = 0;
}
}
// If decelerating and speed is non-zero, slow down
else if(Speed) Speed--;
// Has the speed ramped down to 0?
// If so, set the acceleration flag and reverse the direction.
else if(!Speed)
{
Flags.Accelerate = 1;
Flags.Reverse = ~Flags.Reverse;
}
}
if(Flags.Restart)
{
if(Speed == OldSpeed) Flags.Restart = 0;
else Speed++;
}
// Get the motor speed setting from the potentiometer on AN7
if(!Flags.DirChange && !Flags.Restart)
{
Speed = ReadADC(7);
if(Mode.ACIM || Mode.ACIMTest) Speed >>= 2;
}
if(Mode.ACIMTest)
{
// In test mode, the V_Hz slope is determined by the voltage
// on AN12.
V_Hz_Slope = ReadADC(12) >> 1;
}
else
{
// In the normal ACIM mode, the V/Hz slope is set by a constant.
V_Hz_Slope = V_HZ_SLOPE;
}
// The following code handles the V/Hz profile for the ACIM modes
if(Mode.ACIM || Mode.ACIMTest)
{
// Limit the frequency range.
if(Speed > MOD_FREQ_LIMIT) Speed = MOD_FREQ_LIMIT;
// The following code limits the Amplitude variable that is
// sent to the modulaton routine.
if(V_Hz_Slope == 0) Amplitude = 0;
else
{
// Calculate the maximum speed input setting that will not
// exceed the amplitude limit when multiplied by the
// V_Hz_Slope variable.
temp = HIGH_AMPLITUDE_LIMIT/V_Hz_Slope;
// If the speed input is greater than this, set the Amplitude
// variable at its maximum limit.
// Otherwise, multiply the speed input by the VHz slope to
// get the modulation amplitude.
if(Speed > temp)
Amplitude = HIGH_AMPLITUDE_LIMIT;
else
Amplitude = Speed*V_Hz_Slope;
if(Amplitude < LOW_AMPLITUDE_LIMIT)
Amplitude = LOW_AMPLITUDE_LIMIT;
}
}
if(Mode.BLDC)
{
// Limit the maximum duty cycle
if(Speed > BLDC_SPEED_LIMIT) Speed = BLDC_SPEED_LIMIT;
// Write the new PWM duty cycles.
PDC1 = Speed;
PDC2 = Speed;
PDC3 = Speed;
}
if(Mode.BDC)
{
// Limit the range of duty cycles.
if(Speed > BDC_SPEED_LIMIT) Speed = BDC_SPEED_LIMIT;
// Write the duty cycles to the PWM module.
if(Flags.Reverse)
{
PDC1 = PTPER - Speed;
PDC2 = PTPER + Speed;
}
else
{
PDC1 = PTPER + Speed;
PDC2 = PTPER - Speed;
}
} // end if(Mode.BDC)
// This is the main loop code that responds to a fault event
// signalled by the fault ISR. Here, we just turn on a status
// LED to let the user know that the fault occurred.
// The fault condition is reset when Button 1 is pressed.
if(Flags.PWMFault)
{
LED1 = 1;
}
Flags.MediumEvent = 0;
} //end if(MediumEvent)
//-----------------------------------------------------------------
// Slow event handler executes every 100msec
//-----------------------------------------------------------------
if(Flags.SlowEvent)
{
// These statements check to see if any of the buttons are pressed.
// If so, a software flag is set so the button press can be debounced.
if(BUTTON1) Flags.Button1 = 1;
if(BUTTON2) Flags.Button2 = 1;
if(BUTTON3) Flags.Button3 = 1;
if(BUTTON4) Flags.Button4 = 1;
// Button #1 resets a fault event.
// If button #1 is pressed, a reset signal will be sent to the
// power module to clear any fault LEDs that are lit. Also,
// the PWM channels are re-enabled.
if(Flags.Button1)
{
// Wait until the button is released before doing anything.
if(!BUTTON1)
{
if(Flags.PWMFault)
{
// Reset the speed variable. Save the old speed for use
// in the restart profile.
OldSpeed = Speed;
Speed = 0;
if(Mode.BDC)
{
// Set the duty cycles back to 50%.
PDC1 = PTPER;
PDC2 = PTPER;
PDC3 = PTPER;
}
else
{
PDC1 = 0;
PDC2 = 0;
PDC3 = 0;
}
Flags.Restart = 1;
// Turn the PWM output back on that was disabled in the FLTA ISR
OVDCON = 0x3F00;
// Turn off the status LED
LED1 = 0;
// Reset the power module.
FAULT_RESET = 1;
Nop();
Nop();
Nop();
FAULT_RESET = 0;
// Clear the PWM fault flag
Flags.PWMFault = 0;
}
// Clear the button status flag.
Flags.Button1 = 0;
}
}
// Button2 turns the voltage boost on and off
if(Flags.Button2)
{
LED2 = 1;
if(!BUTTON2)
{
LED2 = 0;
if(IEC0bits.T1IE)
{
IEC0bits.T1IE = 0;
PFC_FIRE = 0;
BRAKE_FIRE = 0;
}
else if(Mode.ACIM || Mode.ACIMTest)
{
IEC0bits.T1IE = 1;
BRAKE_FIRE = 1;
}
Flags.Button2 = 0;
}
}
// Button3 doesn't do anything for this application
if(Flags.Button3)
{
LED3 = 1;
if(!BUTTON3)
{
LED3 = 0;
Flags.Button3 = 0;
}
}
// Button #4 is used to set the direction of the motor.
if(Flags.Button4)
{
// Wait until the button is released before doing anything.
// Start a direction change if one is not already in progress
// and the speed setting is non-zero.
if(!BUTTON4 && !Flags.DirChange && Speed)
{
LED4 = 1;
// Set the direction change flag.
Flags.DirChange = 1;
// Tell the motion profile to decelerate the motor
Flags.Accelerate = 0;
// Save the current Speed setting
OldSpeed = Speed;
// Clear the button status flag
Flags.Button4 = 0;
}
}
Flags.SlowEvent = 0;
} // end if(SlowEvent)
} // end while(1)
} // end main
//---------------------------------------------------------------------
void Setup(void)
{
// Initialize system variables and flags.
Speed = 0;
OldSpeed = 0;
SlowEventCount = SLOW_EVENT_PERIOD;
MediumEventCount = MEDIUM_EVENT_PERIOD;
Mode.ACIM = 0;
Mode.ACIMTest = 0;
Mode.BLDC = 0;
Mode.BDC = 0;
// Initialize PORTs
PORTA = 0;
PORTB = 0; // Initialize PORTs
PORTC = 0;
PORTD = 0;
PORTE = 0;
PORTG = 0;
TRISA = 0x39FF;
TRISB = 0xFFFF;
TRISC = 0xFFF5; // RC1 is LCD R/W line
// RC3 is LCD RS line
TRISD = 0xD7C0; // RD13 is LCD enable line
// RD11 is output for PWM_OUTPUT_ENABLE line
// RD5 is PFC_FIRE line
// RD4 is BRAKE_FIRE line
// RD3:RD0 are LCD data lines
TRISE = 0xFDFF; // RE9 is output for FAULT_RESET line
TRISG = 0xFFFF;
LED1 = 1;
LED2 = 1;
LED3 = 1;
LED4 = 1;
Delay(50000);
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
Delay(50000);
// Initialize the LCD display
OpenXLCD(FOUR_BIT&LINES_5X7);
Delay(50000);
while(BusyXLCD());
SetDDRamAddr(0);
putsXLCD("dsPIC30F MC Demo");
while(BusyXLCD());
SetDDRamAddr(0x40);
putsXLCD("S1-S4 slct mode ");
// Wait for a button to be pressed.
while(!BUTTON1 && !BUTTON2 && !BUTTON3 && !BUTTON4);
Delay(10000);
// Get software mode
if(BUTTON1 && !BUTTON2 && !BUTTON3 && !BUTTON4)
{
LED1 = 1;
while(BUTTON1);
Delay(50000);
Mode.ACIM = 1;
SetDDRamAddr(0x40);
putsXLCD("ACIM Mode 1 ");
LED1 = 0;
}
else if(!BUTTON1 && BUTTON2 && !BUTTON3 && !BUTTON4)
{
LED2 = 1;
while(BUTTON2);
Delay(50000);
SetDDRamAddr(0x40);
putsXLCD("ACIM Mode 2 ");
Mode.ACIMTest = 1;
LED2 = 0;
}
else if(!BUTTON1 && !BUTTON2 && BUTTON3 && !BUTTON4)
{
LED3 = 1;
while(BUTTON3);
Delay(50000);
SetDDRamAddr(0x40);
putsXLCD("BLDC Mode ");
Mode.BLDC = 1;
LED3 = 0;
}
else if(!BUTTON1 && !BUTTON2 && !BUTTON3 && BUTTON4)
{
LED4 = 1;
while(BUTTON4);
Delay(50000);
SetDDRamAddr(0x40);
putsXLCD("Brush DC Mode ");
Mode.BDC = 1;
LED4 = 0;
}
else
{
Delay(50000);
SetDDRamAddr(0x40);
putsXLCD("no mode selected");
}
// Initialize PWM
if(Mode.ACIM || Mode.ACIMTest)
{
PTPER = 230; // Value gives 16KHZ center aligned PWM at 7.38MIPS
PDC1 = 0;
PDC2 = 0;
PDC3 = 0;
PDC4 = 0;
PWMCON1 = 0x0077; // Enable PWM 1,2,3 pairs for complementary mode
DTCON1 = 0x000F; // Value provides 2us dead time at 7.38 MIPS
DTCON2 = 0;
FLTACON = 0x0007; // Fault A enabled for latched mode on PWM1, 2, and 3
FLTBCON = 0; // Fault B not used.
OVDCON = 0x3F00; // Enable PWM1H,1L, 2H, 2L, 3L, 3H for PWM
PTCON = 0x8002; // Enable PWM for center aligned operation
}
else if(Mode.BLDC)
{
PTPER = 460; // Value gives 16KHZ edge aligned PWM at 7.38MIPS
PDC1 = 0;
PDC2 = 0;
PDC3 = 0;
PDC4 = 0;
PWMCON1 = 0x0777; // Enable PWM 1,2,3 pairs for independent mode
DTCON1 = 0; // Dead time disabled
DTCON2 = 0;
FLTACON = 0x0007; // Fault A enabled for latched mode on PWM1, 2, and 3
FLTBCON = 0; // Fault B not used.
OVDCON = 0x3F00; // Enable PWM1H,1L, 2H, 2L, 3L, 3H for PWM
PTCON = 0x8000; // Enable PWM for edge aligned operation
}
else if(Mode.BDC)
{
PTPER = 460; // Value gives 16KHZ edge aligned PWM at 7.38MIPS
PDC1 = PTPER;
PDC2 = PTPER;
PDC3 = 0;
PDC4 = 0;
PWMCON1 = 0x0033; // Enable PWM 1,2 pairs for complementary mode
DTCON1 = 0x000F; // Value provides 2us dead time at 7.38 MIPS
DTCON2 = 0;
FLTACON = 0x0003; // Fault A enabled for latched mode on PWM1, 2
FLTBCON = 0; // Fault B not used.
OVDCON = 0x0F00; // Enable PWM1H,1L, 2H, and 2L for PWM
PTCON = 0x8000; // Enable PWM for edge aligned operation
}
else
// If no mode is selected, the PWM timebase provides interrupt
// generation only. No PWM outputs are enabled.
{
PTPER = 460; // Value gives 16KHZ edge aligned PWM at 7.38MIPS
PTCON = 0x8000; // Enable PWM for edge aligned operation
}
IFS2bits.PWMIF = 0;
IEC2bits.PWMIE = 1; // Enable PWM interrupts.
IFS2bits.FLTAIF = 0;// Clear the fault A interrupt flag.
IEC2bits.FLTAIE = 1;// Enable interrupts for Fault A
// Initialize ADC
ADCON1 = 0;
ADCON2 = 0;
ADCON3 = 0;
ADPCFG = 0x0003;
ADCHS = 0x0007;
ADCON1bits.ADON = 1;
// Reset any active faults on the motor control power module.
FAULT_RESET = 1;
Delay(10);
FAULT_RESET = 0;
// Configure Timer1, but don't enable interrupts
// Timer 1 is used to drive the PFC circuit
TMR1 = 0;
PR1 = 60;
T1CON = 0x8000;
IFS0bits.T1IF = 0;
IEC0bits.T1IE = 0;
// Enable the driver IC on the motor control PCB
PWM_OUTPUT_DISABLE = 0;
// Ensure PFC switch is off.
PFC_FIRE = 0;
// Turn brake off.
BRAKE_FIRE = 0;
// Ensure FLTA flag is cleared
IFS2bits.FLTAIF = 0;
}
//---------------------------------------------------------------------
int ReadADC(unsigned int channel)
{
int Delay;
if(channel > 0x000F) return(0);
ADCHS = channel;
ADCON1bits.SAMP = 1;
for(Delay = 0; Delay < 20; Delay++);
IFS0bits.ADIF = 0;
ADCON1bits.SAMP = 0;
while(!IFS0bits.ADIF);
return(ADCBUF0);
}
//---------------------------------------------------------------------
// The PWM ISR just sets a software flag to trigger SVM calculations
// in the main software loop.
void __attribute__((__interrupt__)) _PWMInterrupt(void)
{
SlowEventCount--;
if(SlowEventCount == 0)
{
Flags.SlowEvent = 1;
SlowEventCount = SLOW_EVENT_PERIOD;
}
MediumEventCount--;
if(MediumEventCount == 0)
{
Flags.MediumEvent = 1;
MediumEventCount = MEDIUM_EVENT_PERIOD;
}
Flags.PWMEvent = 1;
IFS2bits.PWMIF = 0;
}
//---------------------------------------------------------------------
// The FLTA ISR responds to events on the PWM fault pin.
// This ISR code just turns off all the PWM outputs via the OVDCON
// register and signals the main loop that a problem has occurred.
void __attribute__((__interrupt__)) _FLTAInterrupt(void)
{
// Keep all outputs disabled until we figure out what is going on!
OVDCON = 0;
PFC_FIRE = 0;
// Signal a fault to the main loop.
Flags.PWMFault = 1;
// Clear the FLTA interrupt flag.
IFS2bits.FLTAIF = 0;
}
//---------------------------------------------------------------------
// The Timer1 ISR is used to drive the voltage boost circuit
void __attribute__((__interrupt__)) _T1Interrupt(void)
{
if(++BoostCount > 4)
{
PFC_FIRE = 1;
BoostCount = 0;
}
else
PFC_FIRE = 0;
// Clear the Timer1 interrupt flag.
IFS0bits.T1IF = 0;
}
//---------------------------------------------------------------------
// This is a generic delay routine
void Delay(unsigned int count)
{
unsigned int j;
for(j=0;j<count;j++)
ClrWdt();
}
// end of file
Moderatör tarafında düzenlendi: