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

📄 bldc.c

📁 uCos应用
💻 C
📖 第 1 页 / 共 2 页
字号:

#include <includes.h>


#if SPEED_DET == HALL_QEI  //use hall effect sensor to count speed
	static  uint32  Hall_Count;
#endif

#define MOTOR_STOPPED               0
#define MOTOR_PID_RUNNING  			1
#define MOTOR_OPEN_LOOP_RUNNING 	2

uint32    ulTargetSpeed=0; 
static  uint16 	g_uiPwmCurDuty;
static  uint16 	g_uiPwmPeriod;
uint8 g_bAutoRecSpeed=false;

BOOLEAN g_bForward =true ;
static uint16 g_uiSampleCnt=0;
uint16 g_uiSamplePeriod=1; 

typedef struct
{
 	uint32 ulSpeed;
	uint32 ulDutyPercent;
}SpeedMap;

#define MAX_SPEEDMAP  7
static const SpeedMap g_sSpeedMap[MAX_SPEEDMAP]={
  { 200, (uint32)( (200*100)/(RPM_PER_V*SUP_VOL) ) },
  { 500, (uint32)( (500*100)/ (RPM_PER_V*SUP_VOL) ) },
  { 1000,(uint32)( (1000*100)/ (RPM_PER_V*SUP_VOL) ) },
  { 1500,(uint32)( (1500*100)/ (RPM_PER_V*SUP_VOL) ) },
  { 2000,(uint32)( (2000*100)/ (RPM_PER_V*SUP_VOL) ) },
  { 2500,(uint32)( (2500*100)/ (RPM_PER_V*SUP_VOL) ) },
  { 3000,(uint32)( (3000*100)/ (RPM_PER_V*SUP_VOL) ) },
};


uint8 Speed_Queue[SPEED_NUM_MAX*4+20];


//*****************************************************************************
//
// These define the pair of PWM signals that correspond to each phase of the
// motor.
//
//*****************************************************************************
#define PHASE_A                 (PWM_OUT_0_BIT | PWM_OUT_1_BIT)
#define PHASE_B                 (PWM_OUT_2_BIT | PWM_OUT_3_BIT)
#define PHASE_C                 (PWM_OUT_4_BIT | PWM_OUT_5_BIT)

//*****************************************************************************
//
// These define the PWM signals that correspond to the high and low side FETs
// for each phase of the motor.
//
//*****************************************************************************
#define PHASE_A_H            PWM_OUT_0_BIT
#define PHASE_A_L            PWM_OUT_1_BIT
#define PHASE_B_H            PWM_OUT_2_BIT
#define PHASE_B_L            PWM_OUT_3_BIT
#define PHASE_C_H            PWM_OUT_4_BIT
#define PHASE_C_L            PWM_OUT_5_BIT

/*
static const uint32   FW_HallToPhase[8] ={
		                                    0,
									        PHASE_B_L | PHASE_C_H,
									        PHASE_C_L | PHASE_A_H,
									        PHASE_B_L | PHASE_A_H,
									        PHASE_A_L | PHASE_B_H,
									        PHASE_A_L | PHASE_C_H,
									        PHASE_C_L | PHASE_B_H,
                                            0   
										    };

static const uint32 RW_HallToPhase[8]={
                                         0,
									     PHASE_B_H | PHASE_C_L,
									     PHASE_C_H | PHASE_A_L,
									     PHASE_B_H | PHASE_A_L,
									     PHASE_A_H | PHASE_B_L,
									     PHASE_A_H | PHASE_C_L,
									     PHASE_C_H | PHASE_B_L,
                                         0 
										 };
*/

static const uint32   FW_HallToPhase[8] ={
		                                    0,
									        PHASE_C_L | PHASE_B_H,
									        PHASE_B_L | PHASE_A_H,
									        PHASE_C_L | PHASE_A_H,
									        PHASE_A_L | PHASE_C_H,
									        PHASE_A_L | PHASE_B_H,
									        PHASE_B_L | PHASE_C_H,
                                            0   
										    };

static const uint32 RW_HallToPhase[8]={
                                         0,
									     PHASE_C_H | PHASE_B_L,
									     PHASE_B_H | PHASE_A_L,
									     PHASE_C_H | PHASE_A_L,
									     PHASE_A_H | PHASE_C_L,
									     PHASE_A_H | PHASE_B_L,
									     PHASE_B_H | PHASE_C_L,
                                         0 
										 };
			                            



int32 Bytes_To_Long(uint8 *Buffer)      //4个字节合成一个长整型数
{
  int32 lTemp;

  lTemp=(int32) (Buffer[0]+(Buffer[1]<<8)+(Buffer[2]<<16)+((Buffer[3]& 0x7F)<<24));

  if(Buffer[3] & 0x80)
    return( lTemp*(-1) );
  else
    return(lTemp);
}


void Long_To_Bytes(int32 LongData, uint8 *Buffer) //长整型数分成4个字节
{
  int32 lTemp;
  
  lTemp=LongData;

  if(lTemp<0)
  { 
    lTemp=lTemp*(-1);
    Buffer[3]=( (uint8)( (lTemp>>24) & 0x7F ) ) | 0x80; 
  }
  else
  {
    Buffer[3]=( (uint8)( (lTemp>>24) & 0x7F ) ); 
  }

  Buffer[0]=(uint8)(  lTemp & 0xFF );
  Buffer[1]=(uint8)( (lTemp>>8) & 0xFF );
  Buffer[2]=(uint8)( (lTemp>>16) & 0xFF );
}

static void SetupPWM(void)
{
	//
    // Enable the PWM peripheral.
    //
   	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); //PWM2,3
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); //PWM0,1
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); //PWM4,5
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM);

    //
    // Set the PWM clock divider.
    //
    SysCtlPWMClockSet(SYSCTL_PWMDIV_1);

    //
    // Make the appropriate GPIO pins be PWM outputs instead of GPIO.
    //
    //GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW);
    //GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW);
    //GPIODirModeSet(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW);
	//xxx
	GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0); //PD0/PWM0 for HO1
	GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_1);

    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_0); //PB0/PWM2 for HO2
	GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_1); 

    GPIOPinTypePWM(GPIO_PORTE_BASE, GPIO_PIN_0); //PE0/PWM4 for HO3
	GPIOPinTypePWM(GPIO_PORTE_BASE, GPIO_PIN_1);

    //
    // Set the PWM outputs to a non-inverted state with the signal disabled
    // during fault conditions.
    //
    PWMOutputInvert(PWM_BASE, PHASE_A | PHASE_B | PHASE_C, false);
    PWMOutputFault(PWM_BASE, PHASE_A | PHASE_B | PHASE_C, true);   //PD6  FAULT INPUT

    //
    // Disable the PWM outputs.
    //
    PWMOutputState(PWM_BASE, PHASE_A | PHASE_B | PHASE_C, false);

    //
    // Configure and enable the generators.
    //
    PWMGenConfigure(PWM_BASE, PWM_GEN_0,
                    (PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_SYNC |
                     PWM_GEN_MODE_DBG_STOP));
    PWMGenConfigure(PWM_BASE, PWM_GEN_1,
                    (PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_SYNC |
                     PWM_GEN_MODE_DBG_STOP));
    PWMGenConfigure(PWM_BASE, PWM_GEN_2,
                    (PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_SYNC |
                     PWM_GEN_MODE_DBG_STOP));
    PWMGenEnable(PWM_BASE, PWM_GEN_0);
    PWMGenEnable(PWM_BASE, PWM_GEN_1);
    PWMGenEnable(PWM_BASE, PWM_GEN_2);

    //
    // Set the period of each generator timer.
    //
    g_uiPwmPeriod= (uint16)(SysCtlClockGet() * (PWM_PERIOD * 0.001));  // div=1
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_0, g_uiPwmPeriod);
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_1, g_uiPwmPeriod);
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_2, g_uiPwmPeriod);

    //
    // Set the initial pulse width of the PWM signals to zero.
    //
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_0, 0);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_1, 0);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_2, 0);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_3, 0);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_4, 0);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_5, 0);

    //
    // Synchronize the timers.
    //
    PWMSyncUpdate(PWM_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT | PWM_GEN_2_BIT);
    PWMSyncTimeBase(PWM_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT | PWM_GEN_2_BIT);
}


//*****************************************************************************
//
//! Sets the duty cycle of the PWM outputs.
//!
//! \param ulDutyCycle is the duty cycle for the outputs, specified in clocks.
//!
//! This function will synchronously update the duty cycle of the PWM outputs
//! to the specified value.
//!
//! \return None.
//
//*****************************************************************************

static void SetPWMDutyCycle(uint16 DutyCycle)
{
    //
    // Set the PWM duty cycle for each of the PWM outputs.
    //
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_0, DutyCycle);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_1, DutyCycle);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_2, DutyCycle);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_3, DutyCycle);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_4, DutyCycle);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_5, DutyCycle);

    //
    // Synchronously update them all now.
    //
    PWMSyncUpdate(PWM_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT | PWM_GEN_2_BIT);
}


static void SetupQEI(uint8 Sample_IntPrio)
{
    //
    // See if this part has a QEI peripheral.
    //
 	#if SPEED_DET == HW_QEI
    	//
        // Enable the QEI peripheral.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI);

        //
        // Make the appropriate GPIO pins be QEI inputs instead of GPIO.
        //
        GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_6,
                       GPIO_DIR_MODE_HW);
        GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);

        //
        // Configure the QEI block to capture on both edges, use quadrature
        // signals, and to capture the speed.
        //
        QEIConfigure(QEI_BASE, (QEI_CONFIG_CAPTURE_A_B | QEI_CONFIG_NO_RESET |
                                QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP),
                     0);
        QEIVelocityConfigure(QEI_BASE, QEI_VELDIV_1, SysCtlClockGet()*SAMPLE_PERIOD);

        //
        // Enable velocity timer expiration interrupt.
        //
        QEIIntEnable(QEI_BASE, QEI_INTTIMER);
        IntEnable(INT_QEI);

        //
        // Enable the QEI block.
        //
        QEIEnable(QEI_BASE);
        QEIVelocityEnable(QEI_BASE);

        //
        // Set the QEI interrupt 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.
        //
        IntPrioritySet(INT_QEI, Sample_IntPrio);
	#endif

	#if SPEED_DET == SW_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 | TIMER_CFG_B_CAP_COUNT);

⌨️ 快捷键说明

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