示例#1
0
/**
  * @brief  初始化PWM模块
  *
  * @param  None
  *
  * @retval None
  *
  * @note
  * @verbatim
  *
  * Phase U : EPWM3
  * Phase V : EPWM2
  * Phase W : EPWM1
  *
  * Symmetrical mode
  *
  * EN : GPIO34
  *
  * TZ1(Fault) : EPWM输出高电平,对应IR2316后结果为输出悬空
  *
  * @endverbatim
  */
void InverterInit(void)
{
  EALLOW;
  /* EPWM Clock */
  SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;
  SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1;
  SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1;
  SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC  = 0;

  EPWMGPIOInit();

  EPWNBaseInit(&EPwm1Regs);
  EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;         // Master module
  EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;     // Sync down-stream module, Time-base counter equal to zero

  EPWNBaseInit(&EPwm2Regs);
  EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;          // Slave module
  EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;      // sync flow-through

  EPWNBaseInit(&EPwm3Regs);
  EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;          // Slave module
  EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;      // sync flow-through

  /* EPWM clock synchronize enable */
  SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;

  /* Pre-Charge */
  EnableInverter();
  Uint16 i = 0;
  for (i = 0; i < EPWM_PRECHARGE; i++) {
    DELAY_US(1000);
  }
  DisableInverter();

  // Clear any spurious OV trip
  EPwm1Regs.TZCLR.bit.OST = 1;
  EPwm2Regs.TZCLR.bit.OST = 1;
  EPwm3Regs.TZCLR.bit.OST = 1;

  /* Enable TZ */
  EPwm1Regs.TZSEL.bit.OSHT1 = TZ_ENABLE;          // ePWM1 TZ1 Enable, overcurrent
  EPwm2Regs.TZSEL.bit.OSHT1 = TZ_ENABLE;          // ePWM2 TZ1 Enable, overcurrent
  EPwm3Regs.TZSEL.bit.OSHT1 = TZ_ENABLE;          // ePWM3 TZ1 Enable, overcurrent

  // INT
  PieVectTable.EPWM1_TZINT = &TZ_ISR;
  PieCtrlRegs.PIEIER2.bit.INTx1 = 1;  // Enable INT 2.1 in the PIE
  IER |= M_INT2;                      // Enable CPU Interrupt 2

  // SOC
  EPwm1Regs.ETSEL.bit.SOCASEL  = 2;    // Enable event time-base counter equal to period (TBCTR = TBPRD)
  EPwm1Regs.ETPS.bit.SOCAPRD   = 1;    // Generate pulse on 1st event

  EDIS;
}
示例#2
0
/**
  * @brief  TZ ISR, 用于处理过流等异常情况
  *
  * @param  None
  *
  * @retval None
  */
__interrupt void TZ_ISR(void)
{
  DisableInverter();

  /* TZ as output, display fault status */
  EALLOW;
  GpioCtrlRegs.GPAMUX1.bit.GPIO12  = 0;
  GpioCtrlRegs.GPADIR.bit.GPIO12   = 1;
  GpioDataRegs.GPACLEAR.bit.GPIO12 = 1;
  EDIS;

  while(1);
}
示例#3
0
//###########################################################################//
//					PIE Group 3 - MUXed into CPU INT3						 //
//###########################################################################//
//
//###########################################################################//
//								INT3.1 - EPWM1								 //
//					INVERTER FULL-BRIDGE SWITCHING GENERATOR				 //
//###########################################################################//
//
__interrupt void EPWM1_INT_ISR(void)     // EPWM-1
{
	//static volatile Uint16	GPIO34_count	= 0	;

	PieCtrlRegs.PIEACK.bit.ACK3	= 1;	// Acknowledge the PIE group

	if (PeripheralEn.bit.Inverter == 1)
	{
		if (AdcSignal.V_HVDC < V_AC_OUT_REF)	DisableInverter();	// Inverter should only be on if DC voltage can support 230Vrms

		// ----- Inverter PWM sine look-up ----- //
		sinGen.calc(&sinGen);				// Look up new value from sine table
		EPwm1Regs.CMPA.half.CMPA	= ((DutyScale*sinGen.out1) + BIT15)*CMPA_SCALE;	// Duty cycle will follow sine
		EPwm2Regs.CMPA.half.CMPA	= ((DutyScale*sinGen.out2) + BIT15)*CMPA_SCALE;

		GPIO34_count++;
		flag.bit.Inverter		= 1;
		EPwm1Regs.ETCLR.bit.INT	= 1;	// Clear the interrupt flag
	}
}
示例#4
0
//###########################################################################//
//								INT3.8 - EPWM8								 //
//						PERIODIC STATE CHECKS AND ACTIONS					 //
//###########################################################################//
//
__interrupt void EPWM8_INT_ISR(void)    // EPWM-8
{
	PieCtrlRegs.PIEACK.bit.ACK3	= 1	;	// Acknowledge the PIE group

	if (State.bit.StartupSequence)
	{
		if (PeripheralEn.bit.Inverter)	DisableInverter()	;

		if ( !(LED_Stable_Ctr % 512) )
			{
				data_out.bit.led_ctrl_green	= ~data_out.bit.led_ctrl_green	;
				data_out.bit.led_ctrl_red	= ~data_out.bit.led_ctrl_red	;
			}
		LED_Stable_Ctr++;

		if ( abs(V_DcError) < 30 )
			{
				stableCtr++		;
			}
		else	stableCtr	= 0	;

		if (stableCtr >= 30000)				// Checks for 15 seconds where ISR called every 1/2kHz
		{
			stableCtr				= 0	;
			State.all				= 0	;
			State.bit.InvSoftStart	= 1	;
			State.bit.DcStable		= 1	;
			flag_bc					= 1	;		// Update the LCD screen
		}
	}


	if (State.bit.InvSoftStart)
	{
		if ( !(PeripheralEn.bit.Inverter) )	EnableInverter();

		if (softStartCtr >= 2000)		// Waits 1 sec with ePWM8 @ 2kHz
		{
			DutyScale		= DutyScale + 0.005;	// Inverter output allowable duty cycle increments every 1s
			softStartCtr	= 0;					// Reset the counter
		}
		softStartCtr++	;

		if ( !(LED_Inverter_Ctr++ % 512) )	data_out.bit.led_inverter	= ~(data_out.bit.led_inverter);

		if (DutyScale >= DutyScaleMax)
		{
			State.bit.InvSoftStart		= 0;
			data_out.bit.led_inverter	= 1;
			flag_bc						= 1;		// Update the LCD screen
			softStartCtr				= 0;
		}
	}


	if (State.bit.DcStable)
	{
		if ( abs(V_DcError) > 30 )
		{
			unstableCtr++	;				// If error is too large, check if system has entered instability
			stableCtr	= 0	;
		}
		else if (unstableCtr > 0)	stableCtr++	;

		if (unstableCtr >= 10000)
		{
			State.all		= 0	;
			State.bit.Fault	= 1	;		// If the system has a large error for greater than 5 seconds, change system state
			flag_bc			= 1	;		// Update the LCD screen
		}
		else if (stableCtr >= 20000)		// If signs of instability show, but the system goes back to being stable for at least
		{									//		10 seconds, the counters reset and the system state is unchanged.
			stableCtr	= 0	;
			unstableCtr	= 0	;
		}
	}

	EPwm8Regs.ETCLR.bit.INT		= 1	;	// Clear the interrupt flag
}
示例#5
0
void main(void)
{

	int i=0;					// Loop Variable
	timeout_ctr	= 0	;

//############################ Initialisation ###############################//

						// _SOURCE_
	DeviceInit();		// DeviceInit.c
	InitGpio();			// GpioInit.c
	InitPieVectTable();	// PieVect.c
	InitPieCtrl();		// PieCtrl.c

	InitSci();			// Serial.c
	init_lcd_menu();	// LcdMenu.c
	lcd_init();			// LcdDriver.c

	SineRefInit();		// SineRefInit.c
	AdcInit();			// AdcInit.c
	PwmInit();			// PwmInit.c

	State.all				= 0;
	State.bit.Start			= 1;
	PeripheralEn.bit.Buttons= 1;	// Allow button checks

	EnableInterrupts();				// PieCtrl.c
	DisableInverter();				// Ensure inverter is disabled on start-up

	lcd_position(0x5,0x0);
	lcd_puts("Kingfisher");				// Print introductory message on top line
	lcd_position(0x0,0x1);				// Start Cursor From First Line
	lcd_puts("  Hydro Controller    ");	// Print introductory message on bottom line

	asm(" CLRC INTM, DBGM");			// Enable global interrupts and real-time debug

	CpuTimer0Regs.PRD.all =  COUNTER0_PRD;	// Initialise CPU timer0
	CpuTimer1Regs.PRD.all =  COUNTER1_PRD;	// Initialise CPU timer0



//############################# Polling Loop ################################//

	while(1)
	{

	//#######################################################################//
	//									STATES 								 //
	//#######################################################################//
	//
	//############################ START STATE ##############################//
		if(State.bit.Start)
		{
			asm("NOP");
		}

	//######################### EXCITATION STATE ############################//
		if (State.bit.Excitation)
		{
			data_out.bit.led_ctrl_green	= 1;
			data_out.bit.led_ctrl_red	= 0;

			if ( (AdcSignal.V_HVDC < 50) && (AdcSignal.Shaft_Velocity > 2000) && !(State.bit.Fault) )
			{
//				PeripheralEn.bit.Buttons= 0;

				timeout_ctr++;
				if (timeout_ctr > 3)
				{
					State.all		= 0;
					State.bit.Fault	= 1;
					timeout_ctr		= 0;
				}
				else
				{
					data_out.bit.startup = 1;
					shift_data_out();
					if (CpuTimer0Regs.TCR.bit.TIF == 1)
					{
						for (i=1;i<=2;i++)						// wait 2 seconds
						{
							CpuTimer0Regs.TCR.bit.TIF	= 1;	// Clear flag
							while(!CpuTimer0Regs.TCR.bit.TIF);
						}
					}
					data_out.bit.startup = 0;
					shift_data_out();
					if (CpuTimer0Regs.TCR.bit.TIF == 1)
					{
						for(i=1;i<=3;i++)						// wait 3 seconds
						{
							CpuTimer0Regs.TCR.bit.TIF	= 1;	// Clear flag
							while(!CpuTimer0Regs.TCR.bit.TIF);
						}
					}
				}
			}
			else if ( (AdcSignal.V_HVDC >= 50) && (AdcSignal.V_HVDC < 250) )
			{
				timeout_ctr			= 0;
				State.all			= 0;
				State.bit.Excited	= 1;
				// Perhaps change LCD Screen to message saying "Slowly increase turbine speed to increase voltage."
			}
			else if ( (AdcSignal.V_HVDC > 250) )
			{
				timeout_ctr					= 0;		// Resets the timeout counter for excitation
				State.all					= 0;
				State.bit.StartupSequence	= 1;
			}
		}

	//############################ EXCITED STATE ############################//
		if (State.bit.Excited)
		{
			if (AdcSignal.V_HVDC > 250)
			{
				timeout_ctr					= 0;		// Resets the timeout counter for excitation
				State.all					= 0;
				State.bit.StartupSequence	= 1;
			}
			else
			{
				// !!!!! ADD SOME CODE FOR THIS CONDITION !!!!!
			}
		}

	//############################# FAULT STATE #############################//
		if (State.bit.Fault)
		{
			if (PeripheralEn.bit.Inverter)
			{
				DisableInverter();
				data_out.bit.led_dump1		= 0;
				data_out.bit.led_dump2		= 0;
				data_out.bit.led_inverter	= 0;
				data_out.bit.led_update		= 0;
			}
			data_out.bit.protect_trig	= 1;

			data_out.bit.led_ctrl_green	= 0;
			data_out.bit.led_ctrl_red	= 1;
			if ( !(LED_Fault_Ctr++ % 16384) )
			{
				data_out.bit.led_dump1		= ~(data_out.bit.led_dump1);
				data_out.bit.led_dump2		= ~(data_out.bit.led_dump2);
				data_out.bit.led_inverter	= ~(data_out.bit.led_inverter);
				data_out.bit.led_update		= ~(data_out.bit.led_update);
			}
		}

	//########################### DC STABLE STATE ###########################//
		if (State.bit.DcStable)
		{
			if ( !(PeripheralEn.bit.Inverter) )	EnableInverter();
			data_out.bit.led_ctrl_green	= 1;
			data_out.bit.led_ctrl_red	= 0;
		}

	//############################## TEST STATE #############################//
		if (State.bit.Test)
		{

		}

	//########################### TURNED OFF STATE ##########################//
		if (State.bit.TurnOff)
		{
			data_out.bit.led_ctrl_green	= 0;
			data_out.bit.led_ctrl_red	= 0;
			data_out.bit.led_dump1		= 0;
			data_out.bit.led_dump2		= 0;
			data_out.bit.led_inverter	= 0;
			data_out.bit.led_update		= 0;
		}

	//#######################################################################//
	//								FLAGS 									 //
	//#######################################################################//
	//
	//######################## SCREEN UPDATE FLAG #######################//
		if (flag_bc)
		{
			menu_update_lcd();
			flag_bc = 0;
		}
		asm(" nop");

	//########################### READ IN DATA FLAG #########################//
		if (flag.bit.DataIN)
		{
			shift_data_in();
			check_buttons();
			flag.bit.DataIN = 0;
		}

	//########################## SEND OUT DATA FLAG #########################//
		if (flag.bit.DataOUT)
		{
			shift_data_out();
			flag.bit.DataOUT = 0;
		}

	//######################## HVDC VOLTAGE REGULATION ######################//
		if (flag.bit.V_HVDC)
		{
			if ( !(State.bit.TurnOff) && !(State.bit.Fault) )
			{
				V_DcError	= V_DC_REF - AdcSignal.V_HVDC;			// Calculate the DC error from the reference
				DutyError	= 0.75*K_DC*V_DcError + 0.25*DutyError;	// Modify the dump load duty cycle with respect to the DC error

				if (V_DcError > 0)		// If the DC voltage is less than the reference, dump no power
				{
					EPwm3Regs.CMPA.half.CMPA= 0;
					EPwm3Regs.CMPB			= 0;
				}
				else if (DutyError > DUMP1_DUTY_MAX)
				{
					DutyFeedback			= 1.0*(DUMP1_DUTY_MAX)*DUMP_PRD;
					EPwm3Regs.CMPA.half.CMPA= DutyFeedback;
					DutyFeedback			= 1.0*(DutyError - DUMP1_DUTY_MAX)*DUMP_PRD;
					EPwm3Regs.CMPB			= DutyFeedback;
				}
				else
				{
					DutyFeedback			= 1.0*(DutyError)*DUMP_PRD;
					EPwm3Regs.CMPA.half.CMPA= DutyFeedback;
					EPwm3Regs.CMPB			= 0;
				}
			}else		// If there is a fault or the system is off, dump all power
			{
				EPwm3Regs.CMPA.half.CMPA	= (DUMP1_DUTY_MAX)*DUMP_PRD;	// Dump all power!
				EPwm3Regs.CMPB				= DUMP_PRD;	// Dump all power!
			}

			flag.bit.V_HVDC	= 0;		// Reset the flag
		}


	//###################### SHAFT VELOCITY MEASUREMENT #####################//
		if (ShaftVelocCtr >= 1000)										// Updates the measured velocity every 1000*(1/EPWM8) = 0.5s
		{
			AdcSignal.Shaft_Velocity	= shaftspeedtest; //0.8*(ShaftPulseCtr/0.5)*60 + 0.2*AdcSignal.Shaft_Velocity;	// Where 1 pulse = 1 rotation
			ShaftPulseCtr				= 0;	// { Reset counters
			ShaftVelocCtr				= 0;	// {
		}

	//################### OUTPUT AC VOLTAGE FREQUENCY MEASURE ################//
		if (V_AcOutPrdCtr >= 10)
		{
			AdcSignal.V_AcOut_Freq	= (SYSCLK/ADC_SAMP_PRD+1)*(V_AcOutPrdCtr/FreqOutDivCtr);	// Approximate frequency over at least 10 periods
			AcOutFreqError			= AC_OUT_FREQ - AdcSignal.V_AcOut_Freq;	// Find frequency error
			V_AcOutReqFreq			= V_AcOutReqFreq + 0.05*AcOutFreqError;	// Frequency feedback loop
			sinGen.freq				= V_AcOutReqFreq*(BIT31)*(2*BIT32*INVERTER_PWM_PRD)*(1/(sinGen.step_max*SYSCLK));	// Alter reference sine wave frequency
			V_AcOutPrdCtr			= 0	;	// }
			FreqOutDivCtr			= 0	;	// } Reset counters
		}

	//####################### INVERTER CONTROL #######################//
		if (flag.bit.Inverter)
		{
/* BROKEN	InverterMaxDuty	= V_AC_OUT_REF*(1.0/(AdcSignal.V_HVDC));	// Find the maximum duty cycle necessary to create Vacoutpeak=325V
			DutyScaleMax	= (BIT16*InverterMaxDuty-BIT15)*30.51850948e-6;	// 30.51850948e-6 = 1/(BIT15-1)

			if ( !(State.bit.InvSoftStart) )
			{
				DutyScaleError	= DutyScaleMax - DutyScale;
				DutyScale	= DutyScale + 0.01*DutyScaleError;
				if (DutyScale < 0.2)
				{
				DutyScale	= 0.2;
				ADD SOME CODE IN CASE IT IS DANGEROUS TO GO BELOW 0.2
				}
			}
*/

			// ----- Toggle the onboard LED to show inverter control is active
			if (GPIO34_count >= 4000)						// toggle_time = GPIO34_count_limit/fpwm
			{
				GpioDataRegs.GPBTOGGLE.bit.GPIO34	= 1;	// Toggle the pin
				GPIO34_count	= 0;						// Reset the count
			}

			flag.bit.Inverter	= 0;
		}

	//################### INPUT AC VOLTAGE FREQUENCY MEASURE ################//
		if (V_AcInPrdCtr >= 10)
		{
			AdcSignal.V_AcIn_Freq	= 0.8*((SYSCLK/ADC_SAMP_PRD+1)*(V_AcInPrdCtr/FreqInDivCtr)) + 0.2*(AdcSignal.V_AcIn_Freq);	// Approximate frequency over at least 10 periods
			genSlip					= 100*((AdcSignal.V_AcIn_Freq*60) - (AdcSignal.Shaft_Velocity))/(AdcSignal.V_AcIn_Freq*60);	// Calculates slip: s= 100%*((ns-nr)/ns)
			V_AcInPrdCtr			= 0	;	// }
			FreqInDivCtr			= 0	;	// } Reset counters
		}


/*		if(SendADCResult)
		{
			SendADCResult = 0;

			SerialSendStr("Voltage: ");
			SerialSendInt((int)V_DC_measured);
			SerialSendStr("   PWM1: ");
			SerialSendInt((int)(EPwm3Regs.CMPA.half.CMPA*100.0/(DUMP_PRD*1.0)));
			SerialSendCR();
			SerialSendStr("   PWM2: ");
			SerialSendInt((int)((EPwm3Regs.CMPB*100.0)/(DUMP_PRD*1.0)));
			SerialSendCR();
		}*/

	}

}