void NextPWM2() { //Actualizar DutyCycle //----------------------------------------------------------------------------------------------- if (DutyCycle != DutyCycle02) { Chip_PWM_SetMatch(LPC_PWM1, 6, DutyCycle); //Chip_PWM_Reset(LPC_PWM1); Chip_PWM_LatchEnable(LPC_PWM1, 6, PWM_OUT_ENABLED); DutyCycle02 = DutyCycle; } //Conmutaciones MOSfet //----------------------------------------------------------------------------------------------- switch (StepID2) { case 0: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Q2a[2], PIN_Q2a[2], 1); //Apago Q4 Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Q2a[0], PIN_Q2a[0], 0); //Prendo Q0 break; case 1: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Q2b[1], PIN_Q2b[1], 0); //Apago Q3 inv Cycle = 2; //Prendo Q5 break; case 2: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Q2a[0], PIN_Q2a[0], 1); //Apago Q0 Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Q2a[1], PIN_Q2a[1], 0); //Prendo Q2 break; case 3: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Q2b[2], PIN_Q2b[2], 0); //Apago Q5 Cycle = 0; //Prendo Q1 break; case 4: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Q2a[1], PIN_Q2a[1], 1); //Apago Q2 Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Q2a[2], PIN_Q2a[2], 0); //Prendo Q4 break; default: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Q2b[0], PIN_Q2b[0], 0); //Apago Q1 Cycle = 1; //Prendo Q3 } if (StepID2 > 4) //Si StepID es mayor a 4 reseteo variable StepID { StepID2 = 0; //Count++; } else StepID2++;//Incremento StepID para la siguiente conmutación (6 conmutaciones) Match_Cnt2 = 0; //Reinicio Match_Cnt //Estado anterior cruces zeros //----------------------------------------------------------------------------------------------- //CruceZero02[0] = Chip_GPIO_ReadPortBit(LPC_GPIO, PORT_Z2[0], PIN_Z2[0]); //CruceZero02[1] = Chip_GPIO_ReadPortBit(LPC_GPIO, PORT_Z2[1], PIN_Z2[1]); //CruceZero02[2] = Chip_GPIO_ReadPortBit(LPC_GPIO, PORT_Z2[2], PIN_Z2[2]); //CruceZero02[0] = LPC_GPIO->PIN & 0x0000C000; //CruceZero02[1] = LPC_GPIO2->PIN & 0x00000100; }
//ARRANQUE void Start_Up_Brushless(void) { uint32_t t = 1, dr, dPwr; //Drive at const rate for a few cycles to make sure rotor is synched. //----------------------------------------------------------------------------------------------- Count = 0; NextPWM1(); //Siguiente conmutación NextPWM2(); while (Count < 10) //Primeras 3 conmutaciones a período inicial (lentas) por sincronizmo { while (Match_Cnt1 < StepPeriod); //Delay hasta sig conmutación NextPWM1(); //Siguiente conmutación NextPWM2(); } //Set variables para ecuaciones de arranque //----------------------------------------------------------------------------------------------- dPwr = (start.powerRange[1] - start.powerRange[0])/start.duration; //Diferencia de Duty dr = (start.periodRange[0] -start.periodRange[1])/start.duration; t = 0; //Arranque del Motor (Clock:25MHz, Divisor pwm:1, Ciclos pwm:1000, -> [1 Match_Cnt = 40 MicroSeg] //----------------------------------------------------------------------------------------------- while (StepPeriod > start.periodRange[1]) { while (Match_Cnt1 < StepPeriod);//Delay hasta la siguiente conmutación (bloqueante solo durante arranque) NextPWM1(); //Siguiente conmutación NextPWM2(); DutyCycle = start.powerRange[0] + t * dPwr;//Incremento Duty de manera lineal desde powerRange0 a powerRange1 StepPeriod =start.periodRange[0] - t * dr; //Disminuye período entre conmutaciones de manera exponencial decreciente t++; //desde periodRange0 hasta periodRange1 } DutyCycle = 150; // (150/1000)-> 15% Duty Chip_PWM_SetMatch(LPC_PWM1, 5, DutyCycle); Chip_PWM_SetMatch(LPC_PWM1, 6, DutyCycle); //Chip_PWM_Reset(LPC_PWM1); Chip_PWM_LatchEnable(LPC_PWM1, 5, PWM_OUT_ENABLED); Chip_PWM_LatchEnable(LPC_PWM1, 6, PWM_OUT_ENABLED); }
void InitPWM_motores(uint32_t num_motor) { //Configure PWM channel edge (single) CHANNEL channel={3,4,5,6} (depende el caso) //----------------------------------------------------------------------------------------------- Chip_PWM_SetControlMode(LPC_PWM1, PWM_number[num_motor], PWM_SINGLE_EDGE_CONTROL_MODE, PWM_OUT_DISABLED); //Configure match value for channel channel //----------------------------------------------------------------------------------------------- Chip_PWM_SetMatch(LPC_PWM1, PWM_number[num_motor], 20); //Establezco el valor en clock del Duty (canal PWM_num) / 20 -> 2%Duty Chip_PWM_MatchEnableInt(LPC_PWM1, PWM_number[num_motor]); //Habilito interrupción Chip_PWM_ResetOnMatchDisable(LPC_PWM1, PWM_number[num_motor]); //No reset auto Chip_PWM_StopOnMatchDisable(LPC_PWM1, PWM_number[num_motor]); //No stop Chip_PWM_LatchEnable(LPC_PWM1, PWM_number[num_motor], PWM_OUT_ENABLED); Chip_PWM_Reset(LPC_PWM1); }
void DCDCControl(void) { if(!enableOut) vout = 0; uint16_t voltage = readADC(VOUT_PIN); if(voltage > VLimit) { if(over) { vout = vout - 10; DEBUGOUT("Overvoltage %d\n",voltage); } else { over = true; } } else { over = false; } if(vout > VMAX) vout = VMAX; //Limit duty cycle if(vout < 0) vout = 0; //Minimal duty cycle Chip_PWM_SetMatch(LPC_PWM1, 1, vout); Chip_PWM_LatchEnable(LPC_PWM1, 1, PWM_OUT_ENABLED); Chip_PWM_SetMatch(LPC_PWM1, 2, vout); Chip_PWM_LatchEnable(LPC_PWM1, 2, PWM_OUT_ENABLED); Chip_PWM_SetMatch(LPC_PWM1, 3, vout); Chip_PWM_LatchEnable(LPC_PWM1, 3, PWM_OUT_ENABLED); }
void NextPWM(uint32_t num_motor) { //Actualizar DutyCycle //----------------------------------------------------------------------------------------------- if (DutyCycle[num_motor] != DutyCycle0[num_motor]) { Chip_PWM_SetMatch(LPC_PWM1, PWM_number[num_motor], DutyCycle[num_motor]); //Chip_PWM_Reset(LPC_PWM1); Chip_PWM_LatchEnable(LPC_PWM1, PWM_number[num_motor], PWM_OUT_ENABLED); DutyCycle0[num_motor] = DutyCycle[num_motor]; } //Conmutaciones MOSfet //----------------------------------------------------------------------------------------------- switch (StepID[num_motor]) { case 0: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Qb_[num_motor][2], PIN_Qb_[num_motor][2], 1); //Apago Q4 Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Qb_[num_motor][0], PIN_Qb_[num_motor][0], 0); //Prendo Q0 break; case 1: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Qa_[num_motor][1], PIN_Qa_[num_motor][1], 0); //Apago Q3 //Prendo Q5 Cycle[num_motor] = 2; break; case 2: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Qb_[num_motor][0], PIN_Qb_[num_motor][0], 1); //Apago Q0 Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Qb_[num_motor][1], PIN_Qb_[num_motor][1], 0); //Prendo Q2 break; case 3: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Qa_[num_motor][2], PIN_Qa_[num_motor][2], 0); //Apago Q5 //Prendo Q1 Cycle[num_motor] = 0; break; case 4: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Qb_[num_motor][1], PIN_Qb_[num_motor][1], 1); //Apago Q2 Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Qb_[num_motor][2], PIN_Qb_[num_motor][2], 0); //Prendo Q4 break; default: Chip_GPIO_WritePortBit(LPC_GPIO, PORT_Qa_[num_motor][0], PIN_Qa_[num_motor][0], 0); //Apago Q1 //Prendo Q3 Cycle[num_motor] = 1; } if (StepID[num_motor] > 4) //Si StepID es mayor a 4 reseteo variable StepID { StepID[num_motor] = 0; Count[num_motor]++; } else StepID[num_motor]=StepID[num_motor]+1;//Incremento StepID para la siguiente conmutación (6 conmutaciones) Match_Cnt[num_motor] = 0; //Reinicio Match_Cnt //Estado anterior cruces zeros //----------------------------------------------------------------------------------------------- /*=============[TODAVIA NO ESTA IMPLEMENTADO]========================*/ /* CruceZero0[num_motor][0] = GETPIN(PORT_Z_[num_motor][0], PIN_Z_[num_motor][0]); CruceZero0[num_motor][1] = GETPIN(PORT_Z_[num_motor][1], PIN_Z_[num_motor][1]); CruceZero0[num_motor][2] = GETPIN(PORT_Z_[num_motor][2], PIN_Z_[num_motor][2]); */ /*===================================================================*/ }
/** * @brief Main entry point * @return Nothing */ int main(void) { SystemCoreClockUpdate(); Board_Init(); setupClock(); SystemCoreClockUpdate(); On = true; enableOut = false; controlFlag = false; Board_LED_Set(0, On); DEBUGOUT("Starting\n"); /* Initialize RITimer */ Chip_RIT_Init(LPC_RITIMER); LPC_IOCON->PINSEL[4] |= 0x00000555; //Change this after you know which pwm outputs are needed. LPC_IOCON->PINMODE[3] |= (3 << 6); LPC_IOCON->PINMODE[3] |= (3 << 12); LPC_IOCON->PINSEL[1] |= (1 << 14); LPC_IOCON->PINSEL[1] |= (1 << 16); LPC_IOCON->PINSEL[1] |= (1 << 18); LPC_IOCON->PINSEL[1] |= (1 << 20); LPC_IOCON->PINMODE[1] |= (2 << 14); LPC_IOCON->PINMODE[1] |= (2 << 16); LPC_IOCON->PINMODE[1] |= (2 << 18); LPC_IOCON->PINMODE[1] |= (2 << 20); LPC_SYSCTL->PCLKSEL[0] |= (1 << 12); //PCLK_PWM1 = CCLK LPC_IOCON->PINMODE[4] |= (3 << 26); LPC_SYSCTL->PCONP |= (1 << 17); //Enable clock LPC_SYSCTL->PCLKSEL[1] |= (1 << 30); //PCLKMPWM = CCLK LPC_SYSCTL->PCLKSEL[0] |= (1 << 24); Chip_PWM_Init(LPC_PWM1); LPC_PWM1->PR = 0; Chip_PWM_SetMatch(LPC_PWM1, 0, 3000); Chip_PWM_SetMatch(LPC_PWM1, 1, 1500); Chip_PWM_SetMatch(LPC_PWM1, 2, 1500); Chip_PWM_SetMatch(LPC_PWM1, 3, 1500); Chip_PWM_ResetOnMatchEnable(LPC_PWM1, 0); Chip_PWM_SetCountClockSrc(LPC_PWM1, PWM_CAPSRC_RISING_PCLK, 0); Chip_PWM_SetControlMode(LPC_PWM1, 0, PWM_SINGLE_EDGE_CONTROL_MODE, PWM_OUT_ENABLED); Chip_PWM_SetControlMode(LPC_PWM1, 1, PWM_SINGLE_EDGE_CONTROL_MODE, PWM_OUT_ENABLED); Chip_PWM_SetControlMode(LPC_PWM1, 2, PWM_SINGLE_EDGE_CONTROL_MODE, PWM_OUT_ENABLED); Chip_PWM_LatchEnable(LPC_PWM1, 0, PWM_OUT_ENABLED); Chip_PWM_LatchEnable(LPC_PWM1, 1, PWM_OUT_ENABLED); Chip_PWM_LatchEnable(LPC_PWM1, 2, PWM_OUT_ENABLED); Chip_PWM_LatchEnable(LPC_PWM1, 3, PWM_OUT_ENABLED); Chip_PWM_Enable(LPC_PWM1); Chip_PWM_Reset(LPC_PWM1); Chip_GPIO_Init(LPC_GPIO); LPC_MCPWM->CON_SET |= (1 <<3); DCACSetFreq(1074); LPC_MCPWM->DT = 12; LPC_MCPWM->INTEN_SET |= 1; LPC_MCPWM->INTF_SET |= 1; LPC_MCPWM->CON_SET |= 1; freq = 1074; NVIC_EnableIRQ(RITIMER_IRQn); Chip_ADC_Init(LPC_ADC, &ADCSetup); Chip_ADC_SetBurstCmd(LPC_ADC, DISABLE); /* Configure RIT for a 1s interrupt tick rate */ Chip_RIT_SetTimerInterval(LPC_RITIMER, TIME_INTERVAL); /* LED is toggled in interrupt handler */ vout = 0; voutOldest = 0; voutOld = 0; while (1) { if(controlFlag) { bool emergency = !Chip_GPIO_GetPinState(LPC_GPIO,2,13); emergency |= !Chip_GPIO_GetPinState(LPC_GPIO,2,13); emergency |= !Chip_GPIO_GetPinState(LPC_GPIO,2,13); emergency |= !Chip_GPIO_GetPinState(LPC_GPIO,2,13); emergency |= !Chip_GPIO_GetPinState(LPC_GPIO,2,13); emergency |= !Chip_GPIO_GetPinState(LPC_GPIO,2,13); emergency = !emergency; if(emergency) { enableOut = false; vout = 0; } else { #ifdef enableLoad enableOut = Chip_GPIO_GetPinState(LPC_GPIO,0,28); #else enableOut = true; #endif } Board_LED_Set(0, enableOut); DCDCControl(); DCACControl(); Vmeasure += readADC(VIN_PIN); Imeasure += readADC(CURRENT_PIN); times++; if(times >= delayFactor && enableOut) { DEBUGOUT("%d %d %d %d\n",readADC(VIN_PIN), readADC(VOUT_PIN), readADC(CURRENT_PIN), vout); times = 0; cycles++; if(cycles < ncycles) { #ifdef enableMPPT MPPT(Vmeasure/delayFactor, Imeasure/delayFactor); #endif Vmeasure = 0; Imeasure = 0; } else { cycles = 0; } } if(enablePrev != enableOut) { DEBUGOUT("TOGGLING %d\n",enableOut); } enablePrev = enableOut; controlFlag = false; if(emergency) return 0; } } }