📄 bldc.c
字号:
//
// 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 + -