📄 t0isr.c
字号:
//-----------------------------------------------------------------------------
// Sensorless BLDC Motor Reference Design
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories Inc.
//
// AUTH: KAB
// DATE: 30 AUG 2006
//
// This program provides Sensorless BLDC motor control using the
// 'F310. This software is written specifically for the SBLDC
// reference design hardware. Please see the full application
// note for further information.
//
// Target: C8051F30x
//
// Tool chain: KEIL 'c' full-version required
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f310.h> // SFR declarations
#include <slbdc.h> // macro constants
//-----------------------------------------------------------------------------
// commutation patterns
//-----------------------------------------------------------------------------
const unsigned char code skipPattern[6]=
{071,055,047,066,036,033}; // code in octal
const unsigned char code openPhase[6]=
{0x0C,0x0B,0x0A,0x0C,0x0B,0x0A}; // open phase mux value
const unsigned char code TRamp[192]= // linear acceleration table
{
0xF0, 0x63, 0x4C, 0x40, 0x38, 0x33, 0x2F, 0x2B,
0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1F, 0x1E,
0x1D, 0x1C, 0x1B, 0x1B, 0x1A, 0x19, 0x19, 0x18,
0x18, 0x17, 0x17, 0x16, 0x16, 0x16, 0x15, 0x15,
0x15, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 0x13,
0x12, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
0x0E, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
};
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void StartMotor(void);
void T0_Init(void);
void T0_ISR (void);
void stop(void);
void align(void);
void start(void);
void start0(void);
void start7(void);
void run(void);
void run0(void);
void run1(void);
void run2(void);
void run3(void);
unsigned int avgCurrent(void);
signed int avgVoltage(void);
signed int avgVmid(void);
signed int avgVdelta(void);
signed int flip(signed int);
void updateT(void);
void commutate();
void error(void);
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
// Public accessed by GUI
unsigned char Status; // motor state variable
unsigned int Imotor; // motor current measurement
unsigned int Vpot; // speed pot voltage measurement
signed int Vemf;
signed int Verror; // error voltage from min-point voltage
bit Stall; // stall flag bit
bit OverCurrent; // over-current flag bit
// Local global T0_ISR variables
unsigned char Tslot;
unsigned int NextT;
unsigned char AccIndex;
unsigned char MtrIndex;
signed int idata Vmid[6]; // used for avg Verror calc
signed int idata Vdelta[6]; // used for average Vdelta calc
signed int Vmin;
signed int Vmax;
bit Flip;
sbit AlignLED = P0^2;
sbit BlinkLED = P0^3;
// external T2_ISR variables
extern unsigned char Speed;
//-----------------------------------------------------------------------------
// StartMotor function - called from main
//-----------------------------------------------------------------------------
void StartMotor(void)
{
TL0 = 0xF0; // T0 overflow in 16 ticks
TH0 = 0xFF; // msb set to FF
ET0 = 1; // enable T0 interrupt
TR0 = 1; // start Timer0
MtrIndex = 5; // MtrIndex will flip to 0
Status = ALIGN; // set Status to ALIGN state
AlignLED = ON; // turn on LED
Tslot = 0; // commutate on next ISR
Speed = 0; // reset speed ramp controller
}
//-----------------------------------------------------------------------------
// T0_Init - called from main
//-----------------------------------------------------------------------------
void T0_Init(void)
{
TMOD &= ~0x03; // clear T0 mode
TMOD |= 0x01; // T0 mode 1
CKCON &= ~0x07; // clear SCAx and T0M
CKCON |= 0x02; // T0 uses SYSCLK/48
IP |= 0x02; // T0 high priority
CKCON |= 0x10; // T2 uses SYSCLK
TMR2RLL = T2_RELOAD_L; // Timer 2 Low Byte
TMR2RLH = T2_RELOAD_H; // Timer 2 High Byte
}
//-----------------------------------------------------------------------------
// T0_ISR
//-----------------------------------------------------------------------------
void T0_ISR (void) interrupt 1
{
if (Tslot==0) commutate(); // commutate first if time slot zero
switch(Status) // implement state diagram
{
case STOP:
stop(); // stop motor
break;
case ALIGN:
align(); // align motor
break;
case START:
start(); // start motor
break;
case RUN:
run(); // run
break;
}
updateT(); // update T before returning
}
//-----------------------------------------------------------------------------
// stop() called from T0_ISR()
//-----------------------------------------------------------------------------
void stop (void)
{
PCA0CPH0 = 0; // reset duty cycle
PCA0CPH1 = 0; // reset duty cycle
PCA0CPM0 = 0x00; // disable PWM
PCA0CPM1 = 0x00; // disable PWM
ET0 = 0; // disable T0 interrupt
ET2 = 0; // disable T2 interrupt
TR0 = 0; // stop Timer 0
TMR2CN &= ~0x04; // stop Timer 2
}
//-----------------------------------------------------------------------------
// align() called from T0_ISR()
//-----------------------------------------------------------------------------
void align(void)
{
static unsigned char v=0;
static unsigned char d=0;
Tslot = 1; // don't commutate
NextT = TENMS; // execute align every 10ms
if(v < (128 + VLIMIT)) // ramp voltage to 50% + VLIMIT
{
v++; // increment v
PCA0CPH0 = v; // update PWM
PCA0CPH1 = v; // update PWM
}
else if (d < TALIGN) // align delay
{
d++; // increment d
}
else
{
Status = START; // go to next state
AccIndex = 0; // reset table index
Tslot = 0; // commutate on next interrupt
AlignLED = OFF; // turn off LED
v = 0; // clear v for next restart
d = 0; // clear d for next restart
}
}
//-----------------------------------------------------------------------------
// start() called from T0_ISR()
//-----------------------------------------------------------------------------
void start(void)
{
switch(Tslot) // implement time slot manager
{
case 0:
start0(); // do start0() one of eight times
break;
case 7:
start7(); // check if done
break;
}
Tslot++; // increment time slot
Tslot &= 0x07; // mask to 3 bits (modulus 8)
}
//-----------------------------------------------------------------------------
// start0()
//-----------------------------------------------------------------------------
void start0(void)
{
unsigned int t,v;
unsigned char d;
t = TRamp[AccIndex]; // look-up table value
v = VSTART / t; // divide to get v
t *= TSCALE; // scale to get t
v += 128; // add 50%
v += VLIMIT; // add VLIMIT
if(v > 255) // limit to unsigned char
{
v = 255;
}
d = v; // copy to unsigned char d
PCA0CPH0 = d; // update PWM
PCA0CPH1 = d; // update PWM
AccIndex++; // increment index
NextT = t; // update next T
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -