⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtc.c

📁 该程序是ST7MC驱动BLDC120
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 + -