本應用筆記介紹一種采用 dsPIC ® 數字信號控制器
(Digital Signal Controller, DSC)或 PIC24 單片機來實現無刷直流 (Brushless Direct Current, BLDC)電機無傳感器控制的算法。該算法利用對反電動勢(Back-Electromotive Force,BEMF)進行數字濾波的擇多函數來實現。通過對電機的每一相進行濾波來確定電機驅動電壓換相的時刻。這一控制技術省卻了分立的低通濾波硬件和片外比較器。需指出,這里論述的所有內容及應用軟件,都是假定使用三相電機。該電機控制算法包括四個主要部分:
• 利用 DSC 或單片機的模數轉換器(Analog-to-Digital Converter,ADC)來采樣梯形波 BEMF 信號
• PWM 導通側 ADC 采樣,以降低噪聲并解決低電感問題
• 將梯形波BEMF信號與V BUS /2進行比較,以檢測過零點
• 用擇多函數濾波器對比較結果信號進行濾波
• 以三種不同模式對電機驅動電壓進行換相:
- 傳統開環控制器
- 傳統閉環控制器
- 比例 - 積分(Proportional-Integral,PI)閉環
控制器
0.png (12.44 KB, 下載次數: 80)
下載附件
2018-12-29 16:33 上傳
單片機源程序如下:
- /************************************************************************************************************************
- * ?2011 Microchip Technology Inc.
- *
- * MICROCHIP SOFTWARE NOTICE AND DISCLAIMER:
- *
- * You may use this software, and any derivatives
- * created by any person or entity by or on your behalf, exclusively with Microchip抯 products.
- * Microchip and its licensors retain all ownership and intellectual property rights in the
- * accompanying software and in all derivatives hereto.
- *
- * This software and any accompanying information is for suggestion only.
- * It does not modify Microchip抯 standard warranty for its products. You agree that you are
- * solely responsible for testing the software and determining its suitability.
- * Microchip has no obligation to modify, test, certify, or support the software.
- *
- * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY,
- * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR
- * A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE, ITS INTERACTION WITH MICROCHIP扴 PRODUCTS, COMBINATION WITH
- * ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
- *
- * IN NO EVENT, WILL MICROCHIP BE LIABLE, WHETHER IN CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE OR BREACH
- * OF STATUTORY DUTY), STRICT LIABILITY, INDEMNITY, CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, SPECIAL, PUNITIVE,
- * EXEMPLARY, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, FOR COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE,
- * HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST
- * EXTENT ALLOWABLE BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED
- * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
- * MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE TERMS.
- ***********************************************************************************************************************/
- #include "defs.h" //defines, function headers, pi, etc
- #ifdef RTDM_DEMO
- #include "debug.h" //RTDM/DMCI functionality
- #endif
- int main(void)
- {
- Init_Ports(); // Clock ( Fcy 70MHz ) , port configuration, etc
- #ifdef RTDM_DEMO
- DBG_Init(); // RTDM ( Debugger ) Initialization
- #endif
- //defaults: CLKW rotation, motor stopped
- Flags.RunMotor = 0;
- Flags.Startup = 0;
- Flags.CLKW = 1;
- Flags.newCLKW = 1;
- Flags.DMCI_Control_SW = 0; //default potentiometer read
- Timer2Average = TMR2_MAX;
- trigger_count = 1;
- Flags.nb_delay_on = 0;
- #ifdef OPEN_LOOP_CONTROL
- DesiredDuty = MIN_DUTY_CYCLE;
- #else
- DesiredRPM = STARTUP_RPM;
- #endif
- Flags.current_state = STATE_STOPPED;
- while(1) {
-
- if(S2) { //CLKW/CCLKW switch
- while(S2) //debounce
- Delay_100uSec(DEBOUNCE_DELAY*10);
- Flags.newCLKW = !Flags.CLKW;
- }
- if(S3) { //start/stop switch
- while(S3) //debounce
- Delay_100uSec(DEBOUNCE_DELAY*10);
- if(Flags.current_state == STATE_STOPPED)
- Flags.current_state = STATE_STARTING;
- else
- Flags.current_state = STATE_STOPPING;
- }
- switch(Flags.current_state) {
- case STATE_STOPPING:
- Stop_Motor();
- Flags.current_state = STATE_STOPPED;
- break;
- case STATE_STARTING:
- //startup done on MCPWM ISR
- break;
- case STATE_FAULT:
- Stop_Motor();
- Flags.current_state = STATE_STOPPED;
- break;
- case STATE_STARTED:
- if(Flags.newCLKW != Flags.CLKW) {
- Stop_Motor();
- Flags.CLKW = Flags.newCLKW;
- Delay_100uSec(5000); //delay 500 ms for motor to actually stop
- Flags.current_state = STATE_STARTING;
- }
- break;
- case STATE_STOPPED:
- if(Flags.newCLKW != Flags.CLKW)
- Flags.CLKW = Flags.newCLKW;
- break;
- }
- #ifdef RTDM_DEMO
- DBG_SyncComm(); //assure RTDM communication
- #endif
- }
- return 0;
- }
- /*******************************************************************
- Init_Motor()
- Procedure used to initialize all params for the motor and
- for the AN1160 algorithm.
- Also rotor alignment is done here.
- *******************************************************************/
- void Init_Motor()
- {
- int i; //auxiliary counter
- if(Flags.nb_delay_on == 0) {
- T1CONbits.TON = 0;
- T2CONbits.TON = 0;
- TMR1 = 0;
- TMR2 = 0;
- Flags.TrainPI = 0;
-
- //setting direction CLKW or CCLKW
- if(Flags.CLKW == 1) {
- for(i=0;i<6;i++) {
- PWM_STATE1[i] = PWM_STATE1_CLKW[i];
- PWM_STATE2[i] = PWM_STATE2_CLKW[i];
- PWM_STATE3[i] = PWM_STATE3_CLKW[i];
- MotorPhaseAState[i] = MotorPhaseAState_CLKW[i];
- MotorPhaseBState[i] = MotorPhaseBState_CLKW[i];
- MotorPhaseCState[i] = MotorPhaseCState_CLKW[i];
- ADC_CHANNEL[i] = ADC_CHANNEL_CLKW[i];
- ADC_MASK[i] = ADC_MASK_CLKW[i];
- ADC_XOR[i] = ADC_XOR_CLKW[5-i];
- }
- for(i=0;i<64;i++)
- ADC_BEMF_FILTER[i] = ADC_BEMF_FILTER_CLKW[63-i];
- } else {
- for(i=0;i<6;i++) {
- PWM_STATE1[i] = PWM_STATE1_CLKW[5-i];
- PWM_STATE2[i] = PWM_STATE2_CLKW[5-i];
- PWM_STATE3[i] = PWM_STATE3_CLKW[5-i];
- MotorPhaseAState[i] = MotorPhaseAState_CLKW[5-i];
- MotorPhaseBState[i] = MotorPhaseBState_CLKW[5-i];
- MotorPhaseCState[i] = MotorPhaseCState_CLKW[5-i];
- ADC_CHANNEL[i] = ADC_CHANNEL_CLKW[5-i];
- ADC_MASK[i] = ADC_MASK_CLKW[5-i];
- ADC_XOR[i] = ADC_XOR_CLKW[5-i];
- }
- for(i=0;i<64;i++)
- ADC_BEMF_FILTER[i] = ADC_BEMF_FILTER_CLKW[63-i];
- }
-
- stallCount = 0;
- PIDStructure.qInMeas = STARTUP_RPM;
- PIDStructure.qInRef = STARTUP_RPM;
- InitPI(&PIDStructure,SpeedControl_P,SpeedControl_I,PI_ANTI_WINDUP,MAX_DUTY_CYCLE,MIN_DUTY_CYCLE,0);
- TMR2 = TMR2_MAX; //initialize TMR2 and TMR2 average with the value corresponding to the minimum motor speed
- Timer2Value = TMR2;
- Timer2Average = TMR2;
- Timer1Value = 0;
- Flags.RunMotor = 1; // turn the motor ON
- Flags.Startup = 1; // motor initialized, go to starting sequence
-
- ADCCommState = 5; //always start with sector 6 forced
- //set pwm overdrive to the according PWM channel
- IOCON1 = PWM_STATE1[ADCCommState];
- IOCON2 = PWM_STATE2[ADCCommState];
- IOCON3 = PWM_STATE3[ADCCommState];
- CurrentDuty = STARTUP_DUTY; //Init PWM duty cycle value to minimum duty allowed
- PDC1 = CurrentDuty;
- PDC2 = CurrentDuty;
- PDC3 = CurrentDuty;
- nb_delay = ROTOR_ALIGN_T*PWM_100us_FACTOR*10;
- delay_counter = 0;
- Flags.nb_delay_on = 1;
- t_current = STARTUP_START_T*10; //in ms
- t_sector = 0;
- }
- }
- /**********************************************************************
- Start_Motor()
- Procedure for starting the motor according to the implemented
- startup ramp. After the ramp, PI loop training will begin.
- **********************************************************************/
- void Start_Motor()
- {
- if(Flags.nb_delay_on == 0) { //this is just to test if we're not in a non-blocking delay actually
- if(++ADCCommState>5) // Change The Six-Step Commutation Sector
- ADCCommState = 0;
- AD1CHS0 = ADC_CHANNEL[ADCCommState]; //Change ADC Channel AN Selection
- if(t_current < (unsigned long int)STARTUP_T_RAMP*10) {
- t_sector = STARTUP_SEC_C/t_current; //calculates T for 1 sector, in 100s of uS.
- if(t_sector <= 0) t_sector = 1;
- } else
- if (t_current < ((unsigned int)STARTUP_T_RAMP*10 + STARTUP_T_SUST*10)) {
- Flags.TrainPI = 1;
- AD1CON1bits.SSRC = 3;
- }
- else
- Flags.TrainPI = 0;
- //overdrive and output next motor sector
- IOCON1 = PWM_STATE1[ADCCommState];
- IOCON2 = PWM_STATE2[ADCCommState];
- IOCON3 = PWM_STATE3[ADCCommState];
- //here we want a non-blocking delay for the startup to execute
- nb_delay = t_sector * PWM_100us_FACTOR;
- delay_counter = 0;
- Flags.nb_delay_on = 1;
- t_current += t_sector;
- adcBackEMFFilter = 0; //clear the BEMF filter
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
dsPICDEM MCLV-2開發板用戶指南.pdf
(1.18 MB, 下載次數: 51)
2018-12-29 15:23 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
AN1160_dsPIC33EP256MC506_MCLV.rar
(1.04 MB, 下載次數: 67)
2018-12-29 15:23 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|