-
-
Notifications
You must be signed in to change notification settings - Fork 0
MSP430 3Ph
cr88192 edited this page Nov 5, 2015
·
1 revision
Simple 3 Phase driver for MSP430. Written for the MSP430G2232, but should work on bigger chips.
Some features don't really work correctly, but alas.
#include <msp430.h> typedef unsigned char byte; typedef unsigned int uint; typedef unsigned long ulong; #if 0 const byte sintab[64]= { 128, 140, 152, 165, 176, 188, 198, 208, 218, 226, 234, 240, 245, 250, 253, 254, 255, 254, 253, 250, 245, 240, 234, 226, 218, 208, 198, 188, 176, 165, 152, 140, 128, 115, 103, 90, 79, 67, 57, 47, 37, 29, 21, 15, 10, 5, 2, 1, 0, 1, 2, 5, 10, 15, 21, 29, 37, 47, 57, 67, 79, 90, 103, 115 }; #endif const byte sintab1_2[64]= { 128, 167, 184, 196, 206, 215, 223, 229, 235, 240, 244, 247, 250, 252, 254, 255, 255, 255, 254, 252, 250, 247, 244, 240, 235, 229, 223, 215, 206, 196, 184, 167, 128, 88, 71, 59, 49, 40, 32, 26, 20, 15, 11, 8, 5, 3, 1, 0, 0, 0, 1, 3, 5, 8, 11, 15, 20, 26, 32, 40, 49, 59, 71, 88 }; short phase_cnt; short phase_div; short phase_pot; byte phofs[4]; byte phcnt[4]; byte phduty[4]; byte phase; byte dutysc; //duty-cycle scale byte madutysc; //master duty-cycle scale uint vfduty; //VF duty drop-off byte phcnt2[2]; byte phduty2[2]; byte dacm; byte vcsense; byte vcref; byte vcphase; byte (*func)(byte ph); void (*updatePhase)(byte ph); void (*updatePhaseB)(byte ph); byte fix_sin8(byte ph) { return(sintab1_2[(byte)(ph>>2)]); } byte fix_cos8(byte ph) { return(sintab1_2[(byte)((ph+64)>>2)]); } byte fix_sqr8(byte ph) { return((byte)(((signed char)ph)>>7)); } void updateDutyVfDecay(void) { uint i; i=(((ulong)phase_div)*vfduty+128)>>8; if(i>255)i=255; i=((255-i)*madutysc)>>8; dutysc=i; } #if 1 void updatePhase1(byte ph) { int ds; ds=func(phase+phofs[ph]); // ds=(ds*dutysc)>>8; ds=(((ds-128)*dutysc)>>8)+128; phduty[ph]=ds; } void updatePhase1C(byte ph) { phduty[ph]=128; } void updatePhase2(byte ph) { int ds; ds=func(phase+phofs[ph]); ds=(ds<<1)-256; if(ph&1)ds=-ds; if(ds<0)ds=0; ds=(((unsigned int)ds)*dutysc)>>8; // ds=(((ds-128)*dutysc)>>8)+128; phduty[ph]=ds; } #endif void updateVreg(void) { int i; if(vcsense<vcref) { i=phduty2[0]-1; if(i<16)i=16; phduty2[0]=i; }else if(vcsense>vcref) { i=phduty2[0]+1; if(i>240)i=240; phduty2[0]=i; } } void updatePin1(byte ph) { int i; // i=phcnt[ph]+sintab[(byte)(phase+phofs[ph])]; i=phcnt[ph]+phduty[ph]; phcnt[ph]=i; if(i&0x100) { P1OUT|=1<<ph; } else { P1OUT&=~(1<<ph); } } void updatePin2(byte ph) { int i; i=phcnt2[ph]+phduty2[ph]; phcnt2[ph]=i; if(i&0x100) { P2OUT|=1<<ph; } else { P2OUT&=~(1<<ph); } } void clearPhases(void) { phduty[0]=0; phduty[1]=0; phduty[2]=0; phduty[3]=0; phduty2[0]=0; phduty2[1]=0; P1OUT&=~15; P2OUT&=~3; } byte st, lst, nph; struct phaseMode_s { byte phofs[4]; byte (*func)(byte ph); void (*updatePhase)(byte ph); void (*updatePhaseB)(byte ph); byte nph; }; const struct phaseMode_s phaseMode[]={ { 0, 85, 171, 0, fix_sin8, updatePhase1, updatePhase1C, 3}, { 171, 85, 0, 0, fix_sin8, updatePhase1, updatePhase1C, 3}, { 0, 85, 171, 0, fix_sqr8, updatePhase1, updatePhase1C, 3}, { 171, 85, 0, 0, fix_sqr8, updatePhase1, updatePhase1C, 3}, { 0, 0, 64, 64, fix_sin8, updatePhase2, updatePhase2, 4}, { 64, 64, 0, 0, fix_sin8, updatePhase2, updatePhase2, 4}, { 0, 0, 64, 64, fix_sqr8, updatePhase2, updatePhase2, 4}, { 64, 64, 0, 0, fix_sqr8, updatePhase2, updatePhase2, 4} }; void setPhaseMode(byte mode) { struct phaseMode_s *phm; st=mode; lst=st; phm=(struct phaseMode_s *)(&(phaseMode[st])); phofs[0]=phm->phofs[0]; phofs[1]=phm->phofs[1]; phofs[2]=phm->phofs[2]; phofs[3]=phm->phofs[3]; func=phm->func; updatePhase=phm->updatePhase; updatePhaseB=phm->updatePhaseB; nph=phm->nph; } void updateMainPhase(void) { int i; phase=phase+8; phase_cnt=phase_div; updateDutyVfDecay(); updatePhase(0); updatePhase(1); updatePhase(2); updatePhaseB(3); i=P2IN; st=(i>>2)&7; if(st!=lst) { lst=st; setPhaseMode(st); } } void updateMainPhase2(void) { if(!(vcphase++)) { updateVreg(); } if(phase_cnt<=0) { if(phase_div>1012) { clearPhases(); while(phase_div>1012) __bis_SR_register(CPUOFF + GIE); return; } updateMainPhase(); } } int main(void) { BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; // WDTCTL=WDTPW|WDTHOLD; WDTCTL = WDT_MDLY_0_5; //0.5ms at 1MHz (2kHz), 0.03125ms (32kHz) at 16MHz // WDTCTL = WDT_MDLY_0_064; IE1 |= WDTIE; // P1DIR|=0x07; P1DIR|=0x0F; P2DIR|=0x03; P1OUT=0; P2OUT=0; P2REN|=0x1C; // ADC10CTL0 = SREF_1 + ADC10SHT_2 + ADC10ON + ADC10IE + REF2_5V + REFON; ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE + REF2_5V + REFON; ADC10CTL1 = INCH_4; ADC10AE0 |= 0x10; phase_div=16; setPhaseMode(0); dutysc=255; madutysc=255; vfduty=192; dacm=0; ADC10CTL0 |= ENC + ADC10SC; __bis_SR_register(GIE); for(;;) { updatePin1(0); updatePin1(1); updatePin1(2); updatePin1(3); updatePin2(0); updatePin2(1); updateMainPhase2(); } // return 0; } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(ADC10_VECTOR))) ADC10_ISR (void) #else #error Compiler not supported! #endif { unsigned long i; __bic_SR_register_on_exit(CPUOFF); #if 1 switch(dacm) { case 0: phase_pot=ADC10MEM; i=1023-phase_pot; i=(i*i+512)>>10; // i=(i*i*i)>>20; phase_div=i; dacm=1; break; case 1: // dutysc=ADC10MEM>>2; // madutysc=ADC10MEM>>2; dacm=2; break; case 2: vcsense=ADC10MEM>>2; dacm=3; break; case 3: vcref=ADC10MEM>>2; dacm=0; break; default: dacm=0; break; } #endif // phase_div=1024-ADC10MEM; // phase_div=16383-(ADC10MEM<<4); ADC10CTL1 = (ADC10CTL1&0x0FFF)|((4+dacm)<<12); ADC10AE0 = 0x10<<dacm; ADC10CTL0 |= ENC + ADC10SC; } // Watchdog Timer interrupt service routine #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(WDT_VECTOR))) watchdog_timer (void) #else #error Compiler not supported! #endif { phase_cnt--; }