📄 mtc.c
字号:
MCPVL = 0; // Set PWM V to 0%
MCPVH = 0;
#endif
MTC_EnableDirectAccess();
MPHST = 0; // Switch off all drivers
MTC_DisableDirectAccess();
MTC_DisableClock();
MotorStatus &= FAULT_MSK;
Status_Start = INIT_START;
BrakeState = BRAKE_START;
Freq_Motor = 0;
}
#if defined ( __HIWARE__) /* test for HIWARE Compiler */
#pragma TRAP_PROC SAVE_REGS /* additional registers will be saved */
#elif defined ( __CSMC__ ) /* test for Cosmic Compiler */
@interrupt /* Cosmic interrupt handling */
#endif
/*-----------------------------------------------------------------------------
ROUTINE Name : MTC_U_CL_SO_IT
Description: This is the PWM Update interrupt service routine.
Comments: U event taken into account on No action done for BLDC motor drive,
but flags are reset in case the routine is entered.
-----------------------------------------------------------------------------*/
void MTC_U_CL_SO_IT(void)
{
if (MISR & PUI_MSK)
{
MISR = ((u8)~(PUI_MSK));
}
if (MISR & CLI_MSK)
{
MIMR &= ((u8)~(CLIM_MSK)); // disable CL int
MISR = ((u8)~(CLI_MSK));
SetBit(Power_Motor_Status,OverCurrent);
timer_CL_10ms = 30; // 300 ms temporisation
}
SET_MTC_PAGE(1);
if (MCONF & SOI_MSK)
{
MCONF &= ((u8)~(SOI_MSK));
}
SET_MTC_PAGE(0);
}
#if defined ( __HIWARE__) /* test for HIWARE Compiler */
#pragma TRAP_PROC SAVE_REGS /* additional registers will be saved */
#elif defined ( __CSMC__ ) /* test for Cosmic Compiler */
@nosvf @interrupt /* Cosmic interrupt handling */
#endif
/*-----------------------------------------------------------------------------
ROUTINE Name : MTC_C_D_IT
Description: This is the Commutation and Demagnetisation interrupt service
routine.
Comments: None
-----------------------------------------------------------------------------*/
void MTC_C_D_IT(void)
{
if(MISR & CI_MSK)
{
MISR = ((u8)~(CI_MSK));
RPICounter = 0; //reset flag on ratio increment for soft demagnetisation
MPHST = PHASE_CONFIG[StepIndex]; // Preload active phase on next C event
if (!ValBit(Flag_MTC,SWITCH_TO_VOLTAGE_PWMON)) // detect Z during PWM OFF
MCRB = ZC_DEMAG_PWM[StepIndex]; // Active and preload bit of MCRB
else MCRB = ZC_DEMAG_PWM_PWMON[StepIndex]; // detect Z during PWM ON
#if (DRIVING_MODE == VOLTAGE_MODE)
if (RampIndex > 2)
{
if (Commut_Dem_MCPUL != 0 || Commut_Dem_MCPUH != 0) // force duty cycle during demag time?
{
Previous_Duty_L = MCPUL;
Previous_Duty_H = MCPUH;
MCPUL = Commut_Dem_MCPUL; // update duty cycle
MCPUH = Commut_Dem_MCPUH;
}
}
#endif
#if (DEMAG_TYPE == SW)
if (MotorStatus == AUTO_SWITCH)
{
if (!ValBit(Flag_MTC,SWITCH_TO_VOLTAGE_PWMON))
{
if ((u16)(DEMAG_TIME_C[(MPRSR & 0x0f)]+ MCOMP) > U8_MAX)
{
RPICounter ++;
SoftDemagTime = (u16)((DEMAG_TIME_C[(MPRSR & 0x0f)] + MCOMP - 0xFF)/2+ 0x80);
while ((u16)(SoftDemagTime ) > U8_MAX)
{
RPICounter ++;
SoftDemagTime = (((u16)(SoftDemagTime - 0xFF)/2)+ 0x80);
}
}
else MDREG = (u8)(DEMAG_TIME_C[(MPRSR & 0x0f)]+ MCOMP);
}
else
{
if ((u16)(DEMAG_TIME_V[(MPRSR & 0x0f)]+ MCOMP) > U8_MAX)
{
RPICounter ++;
SoftDemagTime = (u16)((DEMAG_TIME_V[(MPRSR & 0x0f)] + MCOMP - 0xFF)/2+ 0x80);
while ((u16)(SoftDemagTime ) > U8_MAX)
{
RPICounter ++;
SoftDemagTime = (((u16)(SoftDemagTime - 0xFF)/2)+ 0x80);
}
}
else MDREG = (u8)(DEMAG_TIME_V[(MPRSR & 0x0f)]+ MCOMP);
}
}
else MDREG = DEMAG_TIME_C[(MPRSR & 0x0f)]; // in starting stage--->so should be in current mode!
// load demagnetization time according to the soft demag time table
#endif
SET_MTC_PAGE(1);
if (!ValBit(Flag_MTC,SWITCH_TO_VOLTAGE_PWMON)) // detect Z during PWM OFF
{
if (ValBit(ZC_DEMAG_PWM[StepIndex],1)) SetBit(MPOL,REO); // read the BEMF on odd channel
else ClrBit(MPOL,REO); // read the BEMF on even channel
}
else // detect Z during PWM ON
{
if (ValBit(ZC_DEMAG_PWM_PWMON[StepIndex],1)) SetBit(MPOL,REO); // read the BEMF on odd channel
else ClrBit(MPOL,REO); // read the BEMF on even channel
}
SET_MTC_PAGE(0);
StepIndex++;
if (StepIndex > 5) StepIndex = 0;
// Autoswitched mode Init
if (MotorStatus & FIRST_AUTO_SWITCH)// ____________________________________
{
u8 i;
MotorStatus &= ((u8)(~FIRST_AUTO_SWITCH));
MotorStatus |= AUTO_SWITCH;
MWGHT = AUTO_DELAY; // Set delay for number of cycle set by AUTO_DELAY_STEP
// MCRA |= DCB; // select MZREG to compute delay
delay_counter = 0; // Initialise the counter to manage delay
for (i=0;i<=STEP_Z_BUFFER_SIZE-1;i++)
{
Step_Z[i].Ratio = RAMP[RampIndex].Ratio; // init buffer for first time computation of the motor frequency
Step_Z[i].StepTime = RAMP[RampIndex].StepTime; // -> avoid wrong PI output & stalled motor status in closed loop operation
}
//PORTS_GreenLedOn(); // Green LED on if autoswitch mode detected
} // end of First auto_switch commutation
if (MotorStatus & AUTO_SWITCH) // Autoswitched mode
{
#if (DEMAG_TYPE == HSW)
if ((MCRB & SDM_MSK)) // soft demag on going
{
if (ValBit(Flag_it,RM_EVT)) // MTIM underflow since last Dh event
SoftDemagTime = (u16)(2*SoftDemagTime);
else SoftDemagTime >>= (u8)(RP_counter); //right shift base on overflow detected
if ((u16)(SoftDemagTime + MCOMP) > U8_MAX)
{
RPICounter ++;
SoftDemagTime = (u16)((SoftDemagTime + MCOMP - 0xFF)/2+ 0x80);
while ((u16)(SoftDemagTime ) > U8_MAX)
{
RPICounter ++;
SoftDemagTime = (((u16)(SoftDemagTime - 0xFF)/2)+ 0x80);
}
}
else MDREG = (u8)(SoftDemagTime + MCOMP);
}
#elif (DEMAG_TYPE == HW) // do nothing! -> hard demagnetization managed by MTC peripheral
#elif (DEMAG_TYPE == SW) // do nothing! -> soft demagnetization managed in C IT
#else
#error"Wrong Demagnetization Type !"
#endif
if ( delay_counter <= MAX_DELAY_COUNTER)
{
delay_counter ++;
if (delay_counter == AUTO_DELAY_STEP)
MWGHT = MEDIUM_DELAY; // Set delay for number of cycle from AUTO_DELAY_STEP
// to MAX_DELAY_COUNTER
}
else
{
if (MCRB & CPB_MSK) MWGHT = Rising_bemf;
else MWGHT = Falling_bemf;
}
} // End of Autoswitched mode
else // Acceleration phase processing
{
if (MotorStatus & LAST_FORCED_SWITCH)// End of switched mode without Z
{
//Calculate Demag Time since MCOMP is new
#if (DEMAG_TYPE == HSW)
MDREG = (u8)(MCOMP / SWITCHED_SW_DEMAG); // Last Demag Time for switched mode
#endif
MCOMP = U8_MAX; // Wait for Z event (no possibility to have C event)
// Prepare autoswitched mode transition
MotorStatus &= ((u8)(~LAST_FORCED_SWITCH));
MotorStatus |= FIRST_AUTO_SWITCH;
MWGHT = TRANSITION_DELAY; //set to 255/256 on first autoswitch step
MCRA |= SWA_MSK; // Enable Autoswitched mode and compute delay on MZPRV
MIMR = ((u8)(RIM_MSK + EIM_MSK + CIM_MSK + ZIM_MSK + DIM_MSK + CLIM_MSK));//...relevant int
} // End of last synchronous mode commutation
else // Forced switched mode without Z detection
{
MCOMP = RAMP[RampIndex].StepTime;
#if (DEMAG_TYPE == HSW)
MDREG = (u8)(MCOMP / SWITCHED_SW_DEMAG);
#endif
RampIndex++; // Next step on the acceleration ramp
UpdateRatio(); // Prepare updation of MTIM prescaler on next C event
if (RampIndex >= (RAMP_SIZE-1)) // If Ramp is finished without success
{
MTC_DisableOutputs();
MTC_DisableClock();
MotorStatus |= START_UP_FAILED;
//SetBit(Power_Motor_Status,StartUpFailed);
//Flash_Red_Led();
}
if (RampIndex == bemf_blank) // Z event masking window is finished
{
SetBit(MIMR,ZIM); // Enable Z event interrupts
}
// Verify if Bemf are present and consecutive (same number of Z and C events)
if ((BemfCounter != 0) // If there was a Z event...
&& (BemfCounter == (u8)(CeventCounter+1))) // ... since last C
{
CeventCounter++;
}
else // Re-start Bemf counting if bemf are not consecutive
{
CeventCounter = 0;
BemfCounter = 0;
}
}
} // End of acceleration phase processing
} // end of C IT
if(MISR & DI_MSK)
{
u8 temp_D;
MISR = ((u8)~(DI_MSK));
#if (DRIVING_MODE == VOLTAGE_MODE)
if (RampIndex > 2)
{
if (Commut_Dem_MCPUL != 0 || Commut_Dem_MCPUH != 0) // force duty cycle during demag time?
{
MCPUL = Previous_Duty_L;
MCPUH = Previous_Duty_H;
}
}
#endif
#if (DEMAG_TYPE == HSW)
if (!(MCRB & SDM_MSK)) // Hard/soft demagnetization
// hard demag done -> compute next soft demag time
{
if (MotorStatus == AUTO_SWITCH) temp_D = (u8)(MDREG - MCOMP); // Demag.time = MDREG - MCOMP
else temp_D = MDREG; // synchronous mode
SoftDemagTime = (temp_D >> 2); // div/4
SoftDemagTime += temp_D; // next MDREG value = 1.25*(hard demag.time)
RP_counter=0; //reset counter of RP event coming between Dhard and next C
ClrBit(Flag_it,RM_EVT);
}
#endif
} // end of demag. interrupt
}
#if defined ( __HIWARE__) /* test for HIWARE Compiler */
#pragma TRAP_PROC SAVE_REGS /* additional registers will be saved */
#elif defined ( __CSMC__ ) /* test for Cosmic Compiler */
@interrupt /* Cosmic interrupt handling */
#endif
/*-----------------------------------------------------------------------------
ROUTINE Name : MTC_R_Z_IT
Description: This is Ratio and zero Crossing interrupt service routine.
Z event -> Autoswitched mode: save step time & ratio values for
speed measurement
Z event -> Switched mode: count number of bemf and enable
autoswitched mode once ramp is finished
RMI event -> no action
RPI event -> Count number of RPI and update MDREG on last one
Comments: The MISR flags are cleared as soon as possible to be able to
serve a new interrupt occuring before the end of the actual one
-----------------------------------------------------------------------------*/
void MTC_R_Z_IT(void)
{
// ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ Z event ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
if (MISR & ZI_MSK)
{
MISR = ((u8)~ZI_MSK); // Reset Z mask
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -