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

📄 bldc.c

📁 uCos应用
💻 C
📖 第 1 页 / 共 2 页
字号:
               
        //
        // Enable the interrupt handler for the timer.
        //
		TimerPrescaleSet(TIMER0_BASE, TIMER_A, 100);  //100 times prescaled
		TimerLoadSet(TIMER0_BASE, TIMER_A, (uint16)(SysCtlClockGet()*SAMPLE_PERIOD*0.01) - 1);
		TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        IntEnable(INT_TIMER0A);
		IntPrioritySet(INT_TIMER0A, Sample_IntPrio);
		//TimerEnable(TIMER0_BASE, TIMER_A);

	    //Set SW QEI input	 , POSITIVE EDGE
		TimerControlEvent(TIMER0_BASE, TIMER_B, TIMER_EVENT_POS_EDGE);
		TimerLoadSet(TIMER0_BASE, TIMER_B, 0xFFFF);
		TimerMatchSet(TIMER0_BASE, TIMER_B, 2);  //interrupt rests counter!!!!!	
 
		TimerIntEnable(TIMER0_BASE, TIMER_CAPB_MATCH);
		IntEnable(INT_TIMER0B);
		//IntPrioritySet(INT_TIMER0B, SwOpt_IntPrio);
		//TimerEnable(TIMER0_BASE, TIMER_B);
	        
        // Set the QEI interrupts to the second highest priority.  It shouldn't
        // be as high as the hall effect sensors (i.e. it shouldn't interfere
        // with commutation of the motor) but it should be handled ahead of the
        // other interrupts.  Both interrupts are set to the same priority as a
        // form of mutual exclusion between the two interrupt handlers (it is
        // guaranteed that one handler will not interrupt the other, so they
        // can share global variables without special consideration of being
        // interrupted by the other).
        //
        
	#endif	

	#if SPEED_DET == HALL_QEI
 		//
        // Enable the timer that will be used to provide the timer period
        // interrupt.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

        //
        // Configure and enable a timer to provide interrupt every 1/100th of a
        // second.
        //
        TimerConfigure(TIMER0_BASE, 
		               TIMER_CFG_16_BIT_PAIR | TIMER_CFG_A_PERIODIC);
               
        //
        // Enable the interrupt handler for the timer.
        //
		TimerPrescaleSet(TIMER0_BASE, TIMER_A, 100);  //100 times prescaled
		TimerLoadSet(TIMER0_BASE, TIMER_A, (uint16)(SysCtlClockGet()*(SAMPLE_PERIOD_UNIT*0.00001)) - 1);
		TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        //IntEnable(INT_TIMER0A);
		IntPrioritySet(INT_TIMER0A, Sample_IntPrio);
		//TimerEnable(TIMER0_BASE, TIMER_A);
	#endif 
}

void StartSpeedSample(void)
{
 	#if SPEED_DET == HW_QEI
		
	#endif

	#if SPEED_DET == SW_QEI
    	TimerEnable(TIMER0_BASE, TIMER_B);
		TimerEnable(TIMER0_BASE, TIMER_A);
	#endif

	#if SPEED_DET == HALL_QEI
		TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);	
		IntEnable(INT_TIMER0A);
		Hall_Count = 0;
		TimerEnable(TIMER0_BASE, TIMER_A);
	#endif
}

void StopSpeedSample(void)
{
 	#if SPEED_DET == HW_QEI
		
	#endif

	#if SPEED_DET == SW_QEI
    
	#endif

	#if SPEED_DET == HALL_QEI
		IntDisable(INT_TIMER0A);
		TimerDisable(TIMER0_BASE, TIMER_A);
	#endif
}

void Sample_Handler(void)
{
  
    uint32 ulTemp;
	uint8 ucBuf[5];

    //OS_CPU_SR cpu_sr=0;	

	//OS_ENTER_CRITICAL();
    //OSIntNesting++;
    //OS_EXIT_CRITICAL();	
			
	#if SPEED_DET == HW_QEI
	    //HW QEI
	    QEIIntClear(QEI_BASE, QEI_INTTIMER);
	#endif
	    
    #if SPEED_DET == SW_QEI 
	 	TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	ulTemp=(uint16)TimerValueGet(TIMER0_BASE, TIMER_B);
		//reset  capture counter
		ulTemp=((0xFFFF - lTemp)* (60/SAMPLE_PERIOD)) / OPT_PULSE_PER_TURN ; //to rpm
    #endif
  
    #if SPEED_DET == HALL_QEI
		TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);	
		g_uiSampleCnt++;
		if(g_uiSampleCnt < g_uiSamplePeriod)
		{ return; }
		else
		{ g_uiSampleCnt=0; }
        ulTemp=Hall_Count;  //hall effect counter/2 =turns counted
		Hall_Count=0;
        //ulTemp=(ulTemp*(10/(SAMPLE_PERIOD_UNIT*g_uiSamplePeriod)));  //(60/SAMPLE_PERIOD)/6	  
		ulTemp= (ulTemp*10000) /(SAMPLE_PERIOD_UNIT*g_uiSamplePeriod);
	#endif

 	if(g_bAutoRecSpeed == true)
	{
		Long_To_Bytes(ulTemp, ucBuf);         //把long型的转速拆成4个byte
		if(g_bForward == false)
		{ ucBuf[3] |=0x80; }
    	QueueWriteN(Speed_Queue, ucBuf, 4);  //转速入队列
	}

    ulTemp =(g_uiPwmCurDuty + PID_DltDutyCycle(ulTargetSpeed-ulTemp)) & 0xFFFF;

    if(ulTemp!=g_uiPwmCurDuty)
	{
     	g_uiPwmCurDuty = ulTemp;		

		if(g_uiPwmCurDuty > g_uiPwmPeriod-5)
		{	g_uiPwmCurDuty = g_uiPwmPeriod-5;	}
		else if(g_uiPwmCurDuty< 5 )
		{ 	g_uiPwmCurDuty = 5;	}

		SetPWMDutyCycle( g_uiPwmCurDuty );
	}
   	
	
	//OSIntExit();
}


//*****************************************************************************
//
//! Hard fault handler.
//!
//! This is the handler for hard faults, if they occur.  Immediate action must
//! be taken to shut off the PWM outputs to prevent any potential damage to the
//! motor.
//!
//! \return None.
//
//*****************************************************************************
void
HardFault_Handler(void)
{
    //
    // Disable all the PWM outputs.
    //
    PWMOutputState(PWM_BASE, PHASE_A | PHASE_B | PHASE_C, false);
 
    while(1);
}

//Initialize hw for bldc
void BLDCInit(uint8 Hall_IntPrio, uint8 Sample_IntPrio) 
{
    
    // Configure the Hall effect GPIO pins as inputs with interrupt generation
    // on both rising and falling edges.
	GPIODirModeSet(HALL_PORT, HALL_A | HALL_B | HALL_C, GPIO_DIR_MODE_IN);
  	GPIOIntTypeSet(HALL_PORT, HALL_A | HALL_B | HALL_C, GPIO_BOTH_EDGES);  
  	//GPIOPinIntEnable(HALL_PORT, HALL_A | HALL_B | HALL_C);  
  	IntEnable(HALL_INT);
    IntPrioritySet(HALL_INT, Hall_IntPrio);

	SetupQEI(Sample_IntPrio);

	SetupPWM();

	QueueCreate(Speed_Queue,             //初始化转速队列                        
                SPEED_NUM_MAX*4+20,
                0,
                0);
}

//
void  Hall_Handler(void)
{
    uint32 ulHall, ulPWM;
    //OS_CPU_SR cpu_sr=0;	

    //
    // Clear the GPIO pin interrupts.
    //
    GPIOPinIntClear(HALL_PORT, HALL_A | HALL_B | HALL_C);
	
	#if SPEED_DET == HALL_QEI
		Hall_Count++;
   	#endif

   //
   // Get the current Hall effect sensor state.
   //
   ulHall = (GPIOPinRead(HALL_PORT, HALL_A | HALL_B | HALL_C) >>
             HALL_SHIFT);

   //
   // Get the set of PWM signals to be driven.
   //
   if(g_bForward == true)
   { ulPWM = FW_HallToPhase[ulHall]; }
   else
   { ulPWM = RW_HallToPhase[ulHall]; }

   //
   // Set the PWM signals to be driven.
   //
   PWMOutputState(PWM_BASE, ulPWM ^ (PHASE_A | PHASE_B | PHASE_C), false);
   PWMOutputState(PWM_BASE, ulPWM, true);
} 


uint8 BLDCStartup(int32 lSpeed)
{
    uint32 ulHall, ulPWM;
	uint32 ulTemp;
	uint8  ucTemp;

	//Set direction
    if(lSpeed>=0)   
    {	g_bForward = true; ulTemp = lSpeed;  }	
	else
	{ 	g_bForward = false; ulTemp = lSpeed *(-1);  }
    
	if(ulTemp>BLDC_MAX_SPEED) 
	{	ulTemp = BLDC_MAX_SPEED; }
	else if(ulTemp<BLDC_MIN_SPEED)
	{ 	ulTemp = BLDC_MIN_SPEED;	}

    ulTargetSpeed = ulTemp;


    for(ucTemp=0; ucTemp<MAX_SPEEDMAP; ucTemp++)
	{
	 	if(ulTemp < g_sSpeedMap[ucTemp].ulSpeed)
		{	break; }
	}

    if(ucTemp==0)
	{	g_uiPwmCurDuty = (uint16) ( (g_sSpeedMap[0].ulDutyPercent*g_uiPwmPeriod)/100 );  }
	else if( ucTemp>0 && ulTemp<g_sSpeedMap[MAX_SPEEDMAP-1].ulSpeed	 )
	{
		//Delta percent of DutyCycle
	    ulPWM =(uint32) ( ((ulTemp-g_sSpeedMap[ucTemp-1].ulSpeed)*
		                   (g_sSpeedMap[ucTemp].ulDutyPercent - g_sSpeedMap[ucTemp-1].ulDutyPercent) 
						  )/
                         (g_sSpeedMap[ucTemp].ulSpeed - g_sSpeedMap[ucTemp-1].ulSpeed) );

        g_uiPwmCurDuty = (uint16) ( (g_sSpeedMap[ucTemp-1].ulDutyPercent + ulPWM)*g_uiPwmPeriod /100 );
	}
	else
	{  g_uiPwmCurDuty = (uint16) ( (g_sSpeedMap[MAX_SPEEDMAP-1].ulDutyPercent*g_uiPwmPeriod)/100 ); }
	
	//
    // Get the current Hall effect sensor state.
    //
	ulHall = (GPIOPinRead(HALL_PORT, HALL_A | HALL_B | HALL_C) >>
              HALL_SHIFT);
         
   	if(g_bForward)
   	{ 	ulPWM = FW_HallToPhase[ulHall]; }
   	else
   	{ 	ulPWM = RW_HallToPhase[ulHall];	}
 
   
   //SetPWMDutyCycle( (uint16)(g_uiPwmPeriod*0.1) );
 
   SetPWMDutyCycle(g_uiPwmCurDuty);
  
   //
   // Set the PWM signals to be driven.
   //
   PWMOutputState(PWM_BASE, ulPWM ^ (PHASE_A | PHASE_B | PHASE_C), false);
   PWMOutputState(PWM_BASE, ulPWM, true);

   
   StartSpeedSample();
   GPIOPinIntEnable(HALL_PORT, HALL_A | HALL_B | HALL_C);  

   return(1);
}

void BLDCHighSizeOff(void)
{
	StopSpeedSample();
	GPIOPinIntDisable(HALL_PORT, HALL_A | HALL_B | HALL_C);
	PWMOutputState(PWM_BASE, PHASE_A_H | PHASE_B_H | PHASE_C_H, false);
	PWMOutputState(PWM_BASE, PHASE_A_L | PHASE_B_L | PHASE_C_L, true);
	SetPWMDutyCycle(g_uiPwmPeriod-5);
}

void BLDCStop(void)
{
	StopSpeedSample();
	GPIOPinIntDisable(HALL_PORT, HALL_A | HALL_B | HALL_C);
	PWMOutputState(PWM_BASE, PHASE_A | PHASE_B | PHASE_C, false);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -