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