📄 mc_stm8s_bldc_drive.c
字号:
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : MC_stm8s_BLDC_drive.c
* Author : IMS Systems Lab
* Date First Issued : mm/dd/yyy
* Description : Low level BLDC drive module
********************************************************************************
* History:
* mm/dd/yyyy ver. x.y.z
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* THIS SOURCE CODE IS PROTECTED BY A LICENSE.
* FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED
* IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
*******************************************************************************/
/* Includes ******************************************************/
#include "MC_dev_drive.h"
#include "stm8s_lib.h"
#include "MC_stm8s_clk_param.h"
#include "MC_stm8s_BLDC_param.h"
#include "MC_Faults.h"
#include "MC_vtimer.h"
#include "MC_BLDC_timers.h"
#include "MC_bldc_motor.h"
#include "MC_BLDC_Motor_Param.h"
#include "MC_BLDC_Drive_Param.h"
#include "MC_PowerStage_Param.h"
#include "MC_ControlStage_Param.h"
#include "MC_BLDC_conf.h" // Include sensor configuration
#ifdef HALL
#include "MC_stm8s_hall_param.h"
#endif
#ifdef DAC_FUNCTIONALITY
#include "MC_dev_DAC.h"
#endif
#ifndef PWM_LOWSIDE_OUTPUT_ENABLE
#define LS_GPIO_CONTROL
#if (defined(LS_GPIO_CONTROL) && (FAST_DEMAG != 0))
#error "Invalid configuration: Is not possible to enable the FAST_DEMAG option with LS_GPIO_CONTROL"
#endif
#endif
/*private prototypes ******************************************************/
void dev_BLDC_driveUpdate(void);
void Application_ADC_Manager( void );
void GetCurrent(void);
void GetSyncUserAdc(void);
void GetBusVoltage(void);
void GetTemperature(void);
void GetNeutralPoint(void);
void GetAsyncUserAdc(void);
void GetStepTime(void);
void SpeedMeasurement(void);
void DebugPinsOff(void);
void Init_TIM1( void );
void Init_TIM2( void );
void TIM2_InitCapturePolarity(void);
void ComHandler(void);
void Commutate_Motor( void );
void StopMotor( void );
void BrakeMotor( void );
u8 BootStrap(void);
u8 AlignRotor( void );
void StartMotor( void );
void Init_ADC( void );
void Enable_ADC_BEMF_Sampling( void );
void Enable_ADC_Current_Sampling( void );
void Enable_ADC_User_Sync_Sampling( void );
u16 CheckMaxDuty(u16 bRequested_Duty);
void DelayCoefAdjust(void);
u16 Set_Duty(u16 duty);
u16 Set_Current(u16 current);
void SetSamplingPoint_BEMF(void);
void SetSamplingPoint_Current(void);
void SetSamplingPoint_User_Sync(void);
#ifdef LS_GPIO_CONTROL
void LS_GPIO_MANAGE(void);
void LS_GPIO_OFF(void);
void LS_GPIO_BRAKE(void);
void LS_GPIO_BOOT(void);
u8 LS_Conf;
#endif
/* Private Typedef */
typedef enum
{STARTUP_IDLE,STARTUP_BOOTSTRAP,STARTUP_ALIGN,STARTUP_START,STARTUP_RAMPING} StartUpStatus_t;
static StartUpStatus_t StartUpStatus = STARTUP_IDLE;
/* Private vars and define */
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define ARRTIM2 500
#ifdef SENSORLESS
#define ARR_CURRENT_REF_TIM ARRTIM2
#endif
#ifdef HALL
#define ARR_CURRENT_REF_TIM hArrPwmVal
#endif
#define MILLIAMP_TOCNT(ma) (((((u32)ma * RS_M)/1000) * AOP * (u32)ARR_CURRENT_REF_TIM)/5000)
#define ADC_TOMILLIAMP(adc) ((((u32)adc * 1000 * 1000) / ((u32)1024 * AOP * RS_M)) * 5)
// Internal global pointer to Device and BLDC struct
pvdev_device_t g_pDevice = 0;
PBLDC_Struct_t g_pBLDC_Struct = 0;
static PBLDC_Var_t g_pMotorVar = 0;
u8 ADC_State;
#define ADC_SYNC 0x00
#define ADC_ASYNC 0x01
u8 ADC_Sync_State = 0x04;
#define ADC_BEMF_INIT 0x00
#define ADC_BEMF_SAMPLE 0x01
#define ADC_CURRENT_INIT 0x12//0x02
#define ADC_CURRENT_SAMPLE 0x13//0x03
#define ADC_USER_SYNC_INIT 0x04
#define ADC_USER_SYNC_SAMPLE 0x05
u8 ADC_Async_State = 0;
#define ADC_BUS_INIT 0x00
#define ADC_BUS_SAMPLE 0x01
#define ADC_TEMP_INIT 0x02
#define ADC_TEMP_SAMPLE 0x03
#define ADC_NEUTRAL_POINT_INIT 0x04
#define ADC_NEUTRAL_POINT_SAMPLE 0x05
#define ADC_USER_ASYNC_INIT 0x06
#define ADC_USER_ASYNC_SAMPLE 0x07
#define SIZE_ADC_BUFFER 6
#define ADC_CURRENT_INDEX 0
#define ADC_USER_SYNC_INDEX 1
#define ADC_BUS_INDEX 2
#define ADC_TEMP_INDEX 3
#define ADC_NEUTRAL_POINT_INDEX 4
#define ADC_USER_ASYNC_INDEX 5
u16 ADC_Buffer[ SIZE_ADC_BUFFER ];
static volatile u8 bCSR_Tmp; // Temporary storage of ADC channel selection
u16 hNeutralPoint;
#define NUMBER_PHASE_STEPS 6
#ifdef ETR_INPUT
#define OCxCE_ENABLE BIT7
#else
#define OCxCE_ENABLE 0
#endif
//select PWM mode 1, OC1 preload enabled, OCxCE enabled.
#define CCMR_PWM (OCxCE_ENABLE|BIT6|BIT5|BIT3)
//select PWM mode 2, OC1 preload enabled, OCxCE enabled. Low Side
#define CCMR_PWM_LS (OCxCE_ENABLE|BIT6|BIT5|BIT3)
//select OCREF - Forced Inactive, OC1 preload enabled (LS Off, HS On) X_COMP mode
#define CCMR_LOWSIDE (BIT6|BIT3)
//select OCREF - Forced Active, OC1 preload enabled (LS ON, HS Off) X_COMP mode
#define CCMR_HIGHSIDE (BIT6|BIT4|BIT3)
#if (PWM_U_LOW_SIDE_POLARITY == ACTIVE_LOW)
#define PWM_POL_LS_A BIT3
#else
#define PWM_POL_LS_A 0
#endif
#if (PWM_U_HIGH_SIDE_POLARITY == ACTIVE_LOW)
#define PWM_POL_HS_A BIT1
#else
#define PWM_POL_HS_A 0
#endif
#define PWM_POL_A PWM_POL_LS_A|PWM_POL_HS_A
#if (PWM_V_LOW_SIDE_POLARITY == ACTIVE_LOW)
#define PWM_POL_LS_B BIT7
#else
#define PWM_POL_LS_B 0
#endif
#if (PWM_V_HIGH_SIDE_POLARITY == ACTIVE_LOW)
#define PWM_POL_HS_B BIT5
#else
#define PWM_POL_HS_B 0
#endif
#define PWM_POL_B PWM_POL_LS_B|PWM_POL_HS_B
#if (PWM_W_LOW_SIDE_POLARITY == ACTIVE_LOW)
#define PWM_POL_LS_C BIT3
#else
#define PWM_POL_LS_C 0
#endif
#if (PWM_W_HIGH_SIDE_POLARITY == ACTIVE_LOW)
#define PWM_POL_HS_C BIT1
#else
#define PWM_POL_HS_C 0
#endif
#define PWM_POL_C PWM_POL_LS_C|PWM_POL_HS_C
#define A_ON (BIT0|PWM_POL_A) // PWM mode on High Side
#define A_ON_LS (BIT2|PWM_POL_A) // PWM mode on Low Side
#ifdef LS_GPIO_CONTROL
#define A_COMP (PWM_POL_A)
#else
#define A_COMP (BIT2|BIT0|PWM_POL_A)
#endif
#define A_OFF PWM_POL_A
#define B_ON (BIT4|PWM_POL_B) // PWM mode on High Side
#define B_ON_LS (BIT6|PWM_POL_B) // PWM mode on Low Side
#ifdef LS_GPIO_CONTROL
#define B_COMP (PWM_POL_B)
#else
#define B_COMP (BIT6|BIT4|PWM_POL_B)
#endif
#define B_OFF PWM_POL_B
#define C_ON (BIT4|BIT0|PWM_POL_C) // PWM mode on High Side
#define C_ON_LS (BIT4|BIT2|PWM_POL_C) // PWM mode on Low Side
#ifdef LS_GPIO_CONTROL
#define C_COMP (BIT4|PWM_POL_C)
#else
#define C_COMP (BIT4|BIT2|BIT0|PWM_POL_C)
#endif
#define C_OFF (BIT4|PWM_POL_C)
// BRK settings
#ifdef BKIN
#define DEV_BKIN TIM1_BREAK_ENABLE
#else
#define DEV_BKIN TIM1_BREAK_DISABLE
#endif
#if (BKIN_POLARITY == ACTIVE_HIGH)
#define DEV_BKIN_POLARITY TIM1_BREAKPOLARITY_HIGH
#else
#define DEV_BKIN_POLARITY TIM1_BREAKPOLARITY_LOW
#endif
#define BEMF_RISING 1
#define BEMF_FALLING 0
#define SAMPLING_POINT_DURING_TOFF_CNT (u16)(((u32)SAMPLING_POINT_DURING_TOFF * STM8_FREQ_MHZ)/1000) // cnt before ARR
#define SAMPLING_POINT_DURING_TON_CNT (u16)(((u32)SAMPLING_POINT_DURING_TON * STM8_FREQ_MHZ)/1000) // cnt after ARR
u16 hDutyCntTh;
u16 hCntDeadDtime;
static const u16 hArrPwmVal = ((u16)((STM8_FREQ_MHZ * (u32)1000000)/PWM_FREQUENCY));
static const u16 hMaxDutyCnt = hArrPwmVal - (((u32)STM8_FREQ_MHZ * MINIMUM_OFF_TIME)/1000);
typedef struct
{
u8 CCMR_1; //Phase A
u8 CCMR_2; //Phase B
u8 CCMR_3; //Phase C
u8 CCER_1;
u8 CCER_2;
} Phase_Step_s;
// CW Steps
//A-Channel1, B-Channel2, C-Channel3
//A(Hi), B(Lo), C-looking, BEMF Falling
//A(Hi), C(Lo), B-looking, BEMF Rising
//B(Hi), C(Lo), A-looking, BEMF Falling
//B(Hi), A(Lo), C-looking, BEMF Rising
//C(Hi), A(Lo), B-looking, BEMF Falling
//C(Hi), B(Lo), C-looking, BEMF Rising
const Phase_Step_s PhaseSteps_CW[ NUMBER_PHASE_STEPS ] =
{
{CCMR_PWM, CCMR_LOWSIDE, CCMR_PWM, (A_ON|B_COMP), C_OFF}, //A-HI, B-Lo, C-Looking
{CCMR_PWM, CCMR_PWM, CCMR_LOWSIDE, (A_ON|B_OFF), C_COMP}, //A-HI, C-Lo, B-Looking
{CCMR_PWM, CCMR_PWM, CCMR_LOWSIDE, (A_OFF|B_ON), C_COMP}, //B-HI, C-Lo, A-Looking
{CCMR_LOWSIDE, CCMR_PWM, CCMR_PWM, (A_COMP|B_ON), C_OFF}, //B-HI, A-Lo, C-Looking
{CCMR_LOWSIDE, CCMR_PWM, CCMR_PWM, (A_COMP|B_OFF), C_ON}, //C-Hi, A-Lo, B-Looking
{CCMR_PWM, CCMR_LOWSIDE, CCMR_PWM, (A_OFF|B_COMP), C_ON} //C-Hi, B-Lo, A-Looking
};
const Phase_Step_s Fast_Demag_Steps_CW[ NUMBER_PHASE_STEPS ] =
{
{CCMR_HIGHSIDE, CCMR_PWM_LS, CCMR_PWM, (A_COMP|B_ON_LS), C_OFF}, //A-HI, B-Lo, C-Looking
{CCMR_PWM, CCMR_PWM, CCMR_LOWSIDE, (A_ON|B_OFF), C_COMP}, //A-HI, C-Lo, B-Looking
{CCMR_PWM, CCMR_HIGHSIDE, CCMR_PWM_LS, (A_OFF|B_COMP), C_ON_LS}, //B-HI, C-Lo, A-Looking
{CCMR_LOWSIDE, CCMR_PWM, CCMR_PWM, (A_COMP|B_ON), C_OFF}, //B-HI, A-Lo, C-Looking
{CCMR_PWM_LS, CCMR_PWM, CCMR_HIGHSIDE, (A_ON_LS|B_OFF), C_COMP}, //C-Hi, A-Lo, B-Looking
{CCMR_PWM, CCMR_LOWSIDE, CCMR_PWM, (A_OFF|B_COMP), C_ON} //C-Hi, B-Lo, A-Looking
};
#ifdef LS_GPIO_CONTROL
#define LS_A BIT0
#define LS_B BIT1
#define LS_C BIT2
#define LS_NOSW BIT0
#define LS_A_B BIT1
#define LS_A_C BIT2
#define LS_B_A BIT3
#define LS_B_C BIT4
#define LS_C_A BIT5
#define LS_C_B BIT6
const u8 LS_Steps_CW[ NUMBER_PHASE_STEPS ] =
{
LS_B,
LS_C,
LS_C,
LS_A,
LS_A,
LS_B
};
const u8 LS_Steps_SW_CW[ NUMBER_PHASE_STEPS ] =
{
LS_NOSW,
LS_B_C,
LS_NOSW,
LS_C_A,
LS_NOSW,
LS_A_B
};
const u8 LS_Steps_CCW[ NUMBER_PHASE_STEPS ] =
{
LS_B,
LS_B,
LS_A,
LS_A,
LS_C,
LS_C
};
const u8 LS_Steps_SW_CCW[ NUMBER_PHASE_STEPS ] =
{
LS_C_B,
LS_NOSW,
LS_B_A,
LS_NOSW,
LS_A_C,
LS_NOSW
};
u8* LS_Steps = LS_Steps_CW;
u8* LS_Steps_SW = LS_Steps_SW_CW;
#endif
Phase_Step_s* PhaseSteps = PhaseSteps_CW;
Phase_Step_s* Fast_Demag_Steps = Fast_Demag_Steps_CW;
// CCW Steps
//A-Channel1, B-Channel2, C-Channel3
//A(Hi), B(Lo), C-looking, BEMF Rising
//C(Hi), B(Lo), A-looking, BEMF Falling
//C(Hi), A(Lo), B-looking, BEMF Rising
//B(Hi), A(Lo), C-looking, BEMF Falling
//B(Hi), C(Lo), A-looking, BEMF Rising
//A(Hi), C(Lo), B-looking, BEMF Falling
const Phase_Step_s PhaseSteps_CCW[ NUMBER_PHASE_STEPS ] =
{
{CCMR_PWM, CCMR_LOWSIDE, CCMR_PWM, (A_ON|B_COMP), C_OFF}, //A-Hi, B-Lo, C-Looking
{CCMR_PWM, CCMR_LOWSIDE, CCMR_PWM, (A_OFF|B_COMP), C_ON}, //C-Hi, B-Lo, A-Looking
{CCMR_LOWSIDE, CCMR_PWM, CCMR_PWM, (A_COMP|B_OFF), C_ON}, //C-Hi, A-Lo, B-Looking
{CCMR_LOWSIDE, CCMR_PWM, CCMR_PWM, (A_COMP|B_ON), C_OFF}, //B-Hi, A-Lo, C-Looking
{CCMR_PWM, CCMR_PWM, CCMR_LOWSIDE, (A_OFF|B_ON), C_COMP}, //B-Hi, C-Lo, A-Looking
{CCMR_PWM, CCMR_PWM, CCMR_LOWSIDE, (A_ON|B_OFF), C_COMP} //A-Hi, C-Lo, B-Looking
};
const Phase_Step_s Fast_Demag_Steps_CCW[ NUMBER_PHASE_STEPS ] =
{
{CCMR_HIGHSIDE, CCMR_PWM_LS, CCMR_PWM, (A_COMP|B_ON_LS), C_OFF}, //A-HI, B-Lo, C-Looking
{CCMR_PWM, CCMR_LOWSIDE, CCMR_PWM, (A_OFF|B_COMP), C_ON}, //C-HI, B-Lo, A-Looking
{CCMR_PWM_LS, CCMR_PWM, CCMR_HIGHSIDE, (A_ON_LS|B_OFF), C_COMP}, //C-HI, A-Lo, B-Looking
{CCMR_LOWSIDE, CCMR_PWM, CCMR_PWM, (A_COMP|B_ON), C_OFF}, //B-HI, A-Lo, C-Looking
{CCMR_PWM, CCMR_HIGHSIDE, CCMR_PWM_LS, (A_OFF|B_COMP), C_ON_LS}, //B-Hi, C-Lo, A-Looking
{CCMR_PWM, CCMR_PWM, CCMR_LOWSIDE, (A_ON|B_OFF), C_COMP} //A-Hi, C-Lo, B-Looking
};
typedef struct
{
u8 BEMF_Level;
u8 ADC_Channel;
} BEMF_Step_s;
// CW Steps
const BEMF_Step_s BEMFSteps_CW[ NUMBER_PHASE_STEPS ] =
{
{BEMF_FALLING, PHASE_C_BEMF_ADC_CHAN},
{BEMF_RISING, PHASE_B_BEMF_ADC_CHAN},
{BEMF_FALLING, PHASE_A_BEMF_ADC_CHAN},
{BEMF_RISING, PHASE_C_BEMF_ADC_CHAN},
{BEMF_FALLING, PHASE_B_BEMF_ADC_CHAN},
{BEMF_RISING, PHASE_A_BEMF_ADC_CHAN}
};
BEMF_Step_s* BEMFSteps = BEMFSteps_CW;
// CCW Steps
const BEMF_Step_s BEMFSteps_CCW[ NUMBER_PHASE_STEPS ] =
{
{BEMF_RISING, PHASE_C_BEMF_ADC_CHAN},
{BEMF_FALLING, PHASE_A_BEMF_ADC_CHAN},
{BEMF_RISING, PHASE_B_BEMF_ADC_CHAN},
{BEMF_FALLING, PHASE_C_BEMF_ADC_CHAN},
{BEMF_RISING, PHASE_A_BEMF_ADC_CHAN},
{BEMF_FALLING, PHASE_B_BEMF_ADC_CHAN}
};
u8 Current_Step;
u8 Current_BEMF;
u8 Current_BEMF_Channel;
u8 MTC_Status;
#define MTC_STEP_MODE BIT0
#define MTC_STARTUP_FAILED BIT1
#define MTC_OVER_CURRENT_FAIL BIT2
#define MTC_LAST_FORCED_STEP BIT3
#define MTC_MOTOR_STALLED BIT4
u8 Phase_State;
#define PHASE_COMM 0x00
#define PHASE_DEMAG 0x01
#define PHASE_ZERO 0x02
u16 Commutation_Time;
u16 Demag_Time;
u16 Zero_Cross_Time;
u16 Previous_Zero_Cross_Time;
u16 Average_Zero_Cross_Time;
u16 LastSwitchedCom;
u16 CurrentLimitCnt;
u8 Ramp_Step;
u8 Zero_Cross_Count;
u8 Last_Zero_Cross_Count;
#define MINIMUM_CONSECTIVE_ZERO_CROSS 12
u8 BEMF_Sample_Debounce;
u8 Z_Detection_Type;
#define Z_DETECT_PWM_OFF 0
#define Z_DETECT_PWM_ON 1
const u16 RAMP_TABLE[ STEP_RAMP_SIZE ] =
{
RAMP_VALUE0,
RAMP_VALUE1,
RAMP_VALUE2,
RAMP_VALUE3,
RAMP_VALUE4,
RAMP_VALUE5,
RAMP_VALUE6,
RAMP_VALUE7,
RAMP_VALUE8,
RAMP_VALUE9,
RAMP_VALUE10,
RAMP_VALUE11,
RAMP_VALUE12,
RAMP_VALUE13,
RAMP_VALUE14,
RAMP_VALUE15,
RAMP_VALUE16,
RAMP_VALUE17,
RAMP_VALUE18,
RAMP_VALUE19,
RAMP_VALUE20,
RAMP_VALUE21,
RAMP_VALUE22,
RAMP_VALUE23,
RAMP_VALUE24,
RAMP_VALUE25,
RAMP_VALUE26,
RAMP_VALUE27,
RAMP_VALUE28,
RAMP_VALUE29,
RAMP_VALUE30,
RAMP_VALUE31,
RAMP_VALUE32,
RAMP_VALUE33,
RAMP_VALUE34,
RAMP_VALUE35,
RAMP_VALUE36,
RAMP_VALUE37,
RAMP_VALUE38,
RAMP_VALUE39,
RAMP_VALUE40,
RAMP_VALUE41,
RAMP_VALUE42,
RAMP_VALUE43,
RAMP_VALUE44,
RAMP_VALUE45,
RAMP_VALUE46,
RAMP_VALUE47,
RAMP_VALUE48,
RAMP_VALUE49,
RAMP_VALUE50,
RAMP_VALUE51,
RAMP_VALUE52,
RAMP_VALUE53,
RAMP_VALUE54,
RAMP_VALUE55,
RAMP_VALUE56,
RAMP_VALUE57,
RAMP_VALUE58,
RAMP_VALUE59,
RAMP_VALUE60,
RAMP_VALUE61,
RAMP_VALUE62,
RAMP_VALUE63
};
u8 Align_State;
#define ALIGN_IDLE 0x00
#define ALIGN_RAMP 0x01
#define ALIGN_DONE 0x02
#define ToCMPxH(CMP,Value) ( CMP = (u8)((Value >> 8 ) & 0xFF))
#define ToCMPxL(CMP,Value) ( CMP = (u8)(Value & 0xFF) )
u8 Align_Target;
u8 Align_Index;
#define CAP_STEP_NUM 6 // Do not change this value
u16 cap_val = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -