📄 mtc.c
字号:
peripheral by toggling the RST bit of the MCRB register.
Input/Output: None
-----------------------------------------------------------------------------*/
void MTC_ResetPeripheral(void)
{
SetBit(MCFR,RST);
ClrBit(MCFR,RST);
}
/*-----------------------------------------------------------------------------
ROUTINE Name : RefreshBootstrap
Description: This function ensures that all high side switch drivers are
correctly supplied when the motor will start. It generates a
1ms pulse on each of the three correspondant low side switches.
All switches are OFF at the end of the routine.
Input/Output: None
Comments: Durations are indicative and are high side driver dependant.
-----------------------------------------------------------------------------*/
void RefreshBootstrap(void)
{
u8 i;
for (i=0; i<3; i++)
{
MPHST = BOOT_REFRESH[i]; // switch ON one low side switch
Wait1ms();
Wait1ms();
MPHST = 0; // Switch OFF all switches
Wait1ms();
Wait1ms();
}
MPHST = 0; // All switches OFF
Wait100us(); // This is to avoid any short circuit conditions
}
/*-----------------------------------------------------------------------------
ROUTINE Name : AlignRotor
Description: After the desired rotor position had been set, this function
increases the stator current to align accordingly the rotor
and prepare the first commutation.
Input/Output: None
Comments: None
-----------------------------------------------------------------------------*/
void AlignRotor(void)
{
u8 i;
u16 DutyCmd, Step_Duty;
u32 temp;
switch (AlignState)
{
case ALIGN_NEXT:
default:
#if (DRIVING_MODE == VOLTAGE_MODE)
Step_Duty = ((u16)(Align_MCPUL+(u16)(Align_MCPUH<<8)))/(ALIGN_STEP_NUM-1);
ToCMPxL(MCPUL,(u16)(Align_Index*Step_Duty)); // increase current (linear curve)
ToCMPxH(MCPUH,(u16)(Align_Index*Step_Duty));
#else
Step_Duty = ((u16)(Align_MCPVL+(u16)(Align_MCPVH<<8)))/(ALIGN_STEP_NUM-1);
ToCMPxL(MCPVL,(u16)(Align_Index*Step_Duty)); // increase current (linear curve)
ToCMPxH(MCPVH,(u16)(Align_Index*Step_Duty));
#endif
Align_Index++;
if (Align_Index == ALIGN_STEP_NUM-1) Status_Start = INIT_SWITCHED_MODE;
AlignState = WAIT_FOR_C;
MISR = 0; // Reset all pending bits
break;
case WAIT_FOR_C:
if (MISR & CI_MSK) AlignState = ALIGN_NEXT;
break;
}
}
/*-----------------------------------------------------------------------------
ROUTINE Name : GetMotorStatus
Description: Allows higher level SW module to get the motor drive module
internal state
Input: None
Output: MotorStatus value
Comments: MotorStatus flags description is public (cf mtc.h)
-----------------------------------------------------------------------------*/
u8 GetMotorStatus(void)
{
return(MotorStatus);
}
/*-----------------------------------------------------------------------------
ROUTINE Name : SetMotorStatus
Description: Allows higher level SW module to set the motor drive module
internal state
Input: MotorStatus value
Output: MNone
Comments: MotorStatus flags description is public (cf mtc.h)
-----------------------------------------------------------------------------*/
void SetMotorStatus(u8 status)
{
MotorStatus = (u8)(status);
}
/*-----------------------------------------------------------------------------
ROUTINE Name : MTC_InitPeripheral
Description: This function (re)initializes the motor control peripheral from
any state (MCU reset, application level initialization, ...).
Input/Output: None
Comments: It must be noticed that part of MPOL and MDTG registers are
write once, meaning they cannot be modified anymore once the
MTC_InitPeripheral function has been executed.
-----------------------------------------------------------------------------*/
void MTC_InitPeripheral(void)
{
MTC_ResetPeripheral();
// Initialize registers in page 1 first
SET_MTC_PAGE(1);
MCONF = mem_MCONF;
MPWME = (u8)(mem_MPWME); // enable PWMV output
MPOL = ALL_ACTIVE_HIGH; // Switch driver input polarity (L6386D)
// ZVD bit=0; Z and D have opposite edge
// REO bit=0;read Z event on even channels
MDTG = mem_MDTG; //reset PCN and write the delay value
MDTG = (u8)(mem_MDTG&(0x40)); // disable the complementary PWM mode
MPAR = OUTPUT_PARITY; // Define Odd/Even MCOx outputs
MZFR = mem_MZFR;
MSCR = mem_MSCR;
// Initialize registers in page 0
SET_MTC_PAGE(0);
MPCR = mem_MPCR;
MCP0L = mem_MCPOL;
MCP0H = mem_MCPOH;
MCRA = mem_MCRA;
MCPUL = 0; // 0% duty cycle on U Channel
MCPUH = 0;
#if (DRIVING_MODE == VOLTAGE_MODE)
MCPVL = mem_MCPVL; // current limitation - Voltage mode
MCPVH = mem_MCPVH;
#else
MCPVL = 0; // 0% duty cycle on V Channel
MCPVH = 0;
#endif
MCRC = mem_MCRC;
MCFR = mem_MCFR;
MDFR = mem_MDFR;
#ifdef EXT_AOP // external circuitry
MREF = CFAV_MASK; // No Chopper, MCCFI input
#else
MREF &= (u8)(~CFAV_MASK); // No Chopper, OAZ input
#endif
MotorStatus = 0; // Needed to manage switched to autoswitched transition
// Indicate motor driving state (start/stop/stalled...)
ClrBit(Flag_MTC,SWITCH_TO_VOLTAGE_PWMON);
PDDDR &= 0xf2; //PD0,PD2,PD3 floating Input
PDOR &= 0xf2;
}
/*-----------------------------------------------------------------------------
ROUTINE Name : MTC_StartMotor
Description: This function performs three actions:
* Initializes HW registers and SW variables needed in real time for motor drive
* prepares the start-up by refreshing the bootstrap capacitors of the high side
switch drivers and aligning the rotor in a known position
* start-up the peripheral circuitry to get expected interrupts
Input/Output: None
-----------------------------------------------------------------------------*/
BOOL MTC_StartMotor(void)
{
switch (Status_Start)
{
default:
case INIT_START:
MTC_InitPeripheral(); // reset the peripheral when restarting
// SW variables init
BemfCounter = 0; // Counts Bemf before autoswitched mode
CeventCounter = 0; // Needed to be sure that Bemf regularly occurs
RPICounter = 0; // When we have to wait until one or several R+
SoftDemagTime = 0;
StepIndex = 0; // Alignment step is the first of the table
RampIndex = 0; // To get the ramp's first step ratio
delay_counter = 0; //counter to manage delay at start_up
Flag_it = 0;
Power_Motor_Status &= Heat_Voltage_Failure; // reset all flags except overtemp & overvoltage
Step_Z_Counter = 0;
Step_counter = Z_event_for_PI; //counter use to validate PI after we pass in autoswitch
Freq_Motor = 0;
Set_CurrentTargetSpeed(Start_Freq);
// Set_DisablePIPeriod(100); // 1 sec delay before entering close loop
timer_after_start=1000;
#ifdef CLOSED_LOOP
Init_PI();
#endif
//PORTS_BothLedOff(); // start command -> LEDs off
#ifndef EXT_AOP
OPAMP_InitOffset(LOW_GAIN); // initialise Opamp Gain and Offset compensation
// OPAMP_InitOffset(HIGHGAIN); // initialise Opamp Gain and Offset compensation
#endif
// Init of MTC peripheral hardware registers used modified during run-time
MIMR = 0;
MPRSR = (u8)(mem_MPRSR + Align_Ratio); // MTIM timer prescaler set-up
MPHST = 0; // All switches OFF
MCRB = 0;
MWGHT = STARTUP_DELAY; // Delay Coefficient in switched mode
MCOMP = (u8)(Align_MCOMP); // Load Alignment time
#if (DEMAG_TYPE == SW)
MDREG = DEMAG_TIME_C[(MPRSR & 0x0f)]; // load demagnetization time according
// to the MTIM ratio prescaler
#else
MDREG = (u8)(Align_MCOMP/4); // Load soft Demag Time
#endif
MTC_EnableDirectAccess();
MTC_EnableOutputs();
RefreshBootstrap(); // To be sure high side driver correctly supplied
MTC_EnableClock();
MPHST = MCIC + START_POSITION; // Alignment step pattern T1+T4+T6
MTC_DisableDirectAccess();
Align_Index = 0;
Status_Start = ALIGN_ON_GOING;
AlignState = WAIT_FOR_C;
MISR = 0;//EI_MSK;
MIMR = EIM_MSK; // enable E interruper
return(FALSE);
break;
case ALIGN_ON_GOING:
AlignRotor(); // Ramp up the alignment current
return(FALSE);
break;
case INIT_SWITCHED_MODE:
#if (DRIVING_MODE == VOLTAGE_MODE)
MCPUL = ramp_MCPUL; // Set duty cycle for ramp up
MCPUH = ramp_MCPUH;
#else
MCPVL = ramp_MCPVL; // set current for ramp up
MCPVH = ramp_MCPVH;
#endif
MTC_DisableClock(); // force 1st ramp ratio value update into MPRSR
MPRSR = (u8)((MPRSR & 0xf0) + RAMP[RampIndex].Ratio); // MTIM timer prescaler set-up
MTC_EnableClock();
StepIndex = 1; // Point to next step configuration
RampIndex = 1; // Alignment completed, prepare the second step of the ramp
UpdateRatio(); // Prepare updation of MTIM prescaler on next C event
MPHST = PHASE_CONFIG[StepIndex]; // Preload active phase on next C event
MCRB = (u8)((ZC_DEMAG_PWM[StepIndex] & Reset_H_SDM_MASK) + SDM_MSK); // Expected Bemf edge, Demag type and PWM behaviour
// Reset both HDM and SDM flag
// & Force SDM bit for next step
StepIndex++; // This is to load the next step config
// when entering the coming C interrupt
//MIMR = ((u8)CIM_MSK + DIM_MSK); // enable C & D interrupt to start commutation mechanism and motor
MIMR = ((u8)CIM_MSK + DIM_MSK + EIM_MSK); // enable C & D & E interrupt to start commutation mechanism and motor
//Status_Start = START_FINISHED;
Status_Start = INIT_START;
BrakeState = BRAKE_START;
return(TRUE);
break;
}
return(FALSE);
}
/*-----------------------------------------------------------------------------
ROUTINE Name : MTC_StopMotor
Description: This function disables all motor control related interrupts
and switch off all transistors. This let the windings in
floating state once they are completely demagnetized.
Input/Output: None
-----------------------------------------------------------------------------*/
void MTC_StopMotor(void)
{
MIMR = 0; // Mask all MTC related interrupts
MCRA &= (u8)(~SWA_MSK); // Disable Autoswitched in previously enabled
#if (DRIVING_MODE == VOLTAGE_MODE)
MCPUL = 0; // Set PWM U to 0%
MCPUH = 0;
#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -