會員登陸
帳號:

密碼:

記住我



忘記密碼?

現在註冊!
網站導航
最新下載
訪問統計 (自2012/5/3)


正在流覽:   1 名訪客





PID程式問題-AN957
新會員
註冊日期:
2016/05/03 21:00
所屬群組:
註冊會員
文章: 18
等級: 2; EXP: 97
HP : 0 / 49
MP : 6 / 153
離線
各位前輩大家好~
AN957裡BLDC Closedloop的PID範例程式有些地方我實在搞不清楚,懇請各位大哥幫忙解惑

問題1.DesiredSpeed = DesiredSpeed*POTMULT;
這邊為什麼要乘一個4倍的轉速比呢?

問題2.DesireSpeed = ADCBUF0; 這邊直接丟10bit的AD數值,那跟轉速有什麼聯繫關西呢?
怎麼可以直接帶入SpeedError = DesiredSpeed - ActualSpeed;去算轉差呢?

問題3.DutyCycle = (((long)Kps*(long)SpeedError + (long)Kis*(long)SpeedIntegral) >> 16);
這裡為什麼右移了16次除65535的原因是?

問題4.程式裡PID控制是由ADC中斷去觸發執行,而ADC中斷又是依PWM控制,那取樣時間=FPWM=39Khz是這個意思嗎?


code太長無法全貼出所以我做了一些刪減,程式是AN957的closedloop程式檔


#include "p30F2010.h"

#define FCY  10000000            // xtal = 5.0Mhz; PLLx8
#define MILLISEC FCY/10000            // 1 mSec delay constant
#define FPWM 39000
#define POLEPAIRS    5        // number of pole pairs of the motor
#define INDEX    1            // Hall sensor position index

#define S2    !PORTCbits.RC14
#define S3    !PORTCbits.RC13

#define CR    0x0D
#define LF     0x0A
#define BAUD 19200
#define SPEEDMULT    2343750        // factor used to calculate speed
#define OFFSET 8            // offset in InData to load speed values
#define POTMULT 4            // pot to speed ratio

#define Kps    750            // Kp and Ks terms need to be adjusted as per
#define Kis    20            // the motor and load


void InitADC10(void);
void AverageADC(void);
void DelayNmSec(unsigned int N);
void InitMCPWM(void);
void InitUART(void);
void SendSpeed(void);
void InitTMR3(void);
void SendMsg(void);
void CalculateDC(void);

unsigned int timer3value;
unsigned int timer3avg;
int DesiredSpeed;
int ActualSpeed;
int SpeedError;
int DutyCycle;
int SpeedIntegral;

/*********************************************************************
The ADC interrupt reads the demand pot value.
*********************************************************************/
void __attribute__((interrupt, no_auto_psv)) _ADCInterrupt (void)
{
    
IFS0bits.ADIF = 0;    
    
DesiredSpeed = ADCBUF0;
    
Flags.CalSpeed = 1;        // after every adc read,  do a PI calculation
}

int main(void)
{
    
LATE = 0x0000;
    
TRISE = 0xFFC0;        // PWMs are outputs
    
CNEN1 = 0x00E0;        // CN5,6 and 7 enabled
    
CNPU1 = 0x00E0;        // enable internal pullups
    
IFS0bits.CNIF = 0;    // clear CNIF
    
IEC0bits.CNIE = 1;    // enable CN interrupt
    
InitMCPWM();
    
InitADC10();
    
InitUART();
    
InitTMR3();
    
timer3avg = 0;
    while(
1)
    {        
        while (!
S2);                // wait for start key hit
        
while (S2)                    // wait till key is released
            
DelayNmSec(10);
        
// read hall position sensors on PORTB
        
HallValue = PORTB & 0x0038;            // mask RB3,4 & 5
        
HallValue = HallValue >> 3;            // shift right to get value = 1, 2 ... 6
        
OVDCON = StateLoTableAntiClk[HallValue];    // Load the overide control register
        
PWMCON1 = 0x0777;                    // enable PWM outputs
        
Flags.RunMotor = 1;                    // set running flag
        
T3CONbits.TON = 1;                    // start tmr3
        
polecount = 1;
        
DelayNmSec(100);
        while (
Flags.RunMotor)                // while motor is running
            
{
            if (
S2)                            // if S2 is pressed, stop
                
{
                
PWMCON1 = 0x0700;            // disable PWM outputs
                  
OVDCON = 0x0000;            // overide PWM low.
                
Flags.RunMotor = 0;            // reset run flag
                
while (S2)                    // wait for key release
                    
DelayNmSec(10);
                }
            if (
Flags.CalSpeed)        // if calculate flag set then
                
{
                
SendSpeed();        // send present speed serially
                
CalculateDC();        // calculate new dutycycle using PI
                
Flags.CalSpeed = 0;        // clear flag
                
}
            }
    }    
// end of while (1)
    

}    // end of main
/*****************************************************************************
CalculateDC, uses the PI algorithm to calculate the new DutyCycle value which
will get loaded into the PDCx registers.
****************************************************************************/

void CalculateDC(void)
{
    
ActualSpeed = SPEEDMULT/timer3avg;
    
DesiredSpeed = DesiredSpeed*POTMULT;
    
SpeedError = DesiredSpeed - ActualSpeed;
            
SpeedIntegral += SpeedError;
    
DutyCycle = (((long)Kps*(long)SpeedError + (long)Kis*(long)SpeedIntegral) >> 16);
    
PDC1 = PDC1 + DutyCycle;    
    if (
PDC1 < 50)
        {
PDC1 = 50;SpeedIntegral = 0;}
    if (
PDC1 > 512)
        {
PDC1 = 512;SpeedIntegral = 0;}
    
PDC2 = PDC1;
    
PDC3 = PDC1;

}

附加檔案:


zip SWAN957.zip 大小: 71.85 KB; 下載次數: 38

2016/10/03 15:41
轉換PDF檔 列印


Re: PID程式問題-AN957
資深會員
註冊日期:
2004/07/23 16:25
所屬群組:
註冊會員
文章: 1150
等級: 29; EXP: 67
HP : 0 / 716
MP : 383 / 26894
離線
見樹不見林~~~

當你用mcu 思考,而不是人思考,就會了解其中的意義

code ,我沒########################OOPS########################嚓飢A看,pid 的原理自己上網看

簡單描述,人類要的定速、皕禳A在mcu 世界不存在速度、溫度

只有 01010101101010 ,你要定的不是速度、溫度

你要定的是一個數~~這個數,可能是溫度、可能速度、可能是轉速,通常都來自adc 或counter

這個數的公式可能 * 123/234.2432+52 =溫度

在mcu 的世界,不存在人類的公式

pid,我的目的很簡單,讓系統固定在一個數

所以為什麼*4,也許只是要放大4倍 也許是要放大 1024倍,為什麼要>>16,也許是為了 /0.0000152587890625

以最簡單溫度換算 f= 32+1.8c

用人腦看算看似簡單,用桌上型電腦來算也很容易,用mcu ,請換個腦袋用mcu來思考

就有可能變成這樣

F=8192 + c<<8 + 0xCCCC*C >>8 (數值放大 256倍)

如果在冷凍庫-10度對人類感覺很直覺,對mcu 跨過0 ,跟本是個麻煩

值就會變成

F=8192 + c<<8 + 0xCCCC*C >>8 +0x7FFF (數值放大256倍,零點位移 0x7FFF)

不會有跨過 0x0000 的問題 (pid 數值overflow 很麻煩的)

2016/10/03 22:01
轉換PDF檔 列印


Re: PID程式問題-AN957
新會員
註冊日期:
2011/08/02 18:14
所屬群組:
註冊會員
文章: 8
等級: 1; EXP: 73
HP : 0 / 18
MP : 2 / 312
離線
您好:

最近有新產品研究,目對dspic較不熟,想請問幾個問題確認,多謝了。

1、AN957,PI控制器是外加於dspic?

2、dspic內有微分、積分函數或指令?,pic18也可以嗎?

3、另一個問題,TC4427及IRFZ24N這組也可用PWM控制(mosfet)?

2016/11/11 09:14
轉換PDF檔 列印


Re: PID程式問題-AN957
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 13936
等級: 72; EXP: 17
HP : 1067 / 1779
MP : 4645 / 67954
離線
我不是馬達專家,但我知道 BLDC Back-EMF 的 PI 是必須以高速計算的,所以 PI 會是以 dsPIC 的組語或 Built_in 巨集來撰寫的。

PI 是在測得不導電的那一相的反電動勢時到下一相的反電動勢之間必須計算出下一個 PWM 的輸出功率,所需求的計算是要很快的,在這裡始使用 dsPIC 來做這高速的計算,不在外面。

dsPIC 有它專屬的 DSP 指令,一般的 PIC24 & PIC18 是沒有的。

2016/11/15 12:07
轉換PDF檔 列印


Re: PID程式問題-AN957
新會員
註冊日期:
2011/08/02 18:14
所屬群組:
註冊會員
文章: 8
等級: 1; EXP: 73
HP : 0 / 18
MP : 2 / 312
離線
多謝了。

2016/11/19 09:30
轉換PDF檔 列印






無法在此發表文章
可以在此觀看文章
無法回覆文章
無法編輯自己的文章
無法刪除自己的文章
無法發起投票調查
無法在此投票
無法上傳附加檔案
無法不經審核直接發表文章

[進階搜尋]


搜尋
線上教學影片
網頁捷徑
教育訓練
其它網站連結
電話: 02-25000405
產品技術問題產品技術支援專線:0800-717718 台北02-25088600 新竹03-5778366 Ext. 8600 高雄07-2137830 MicrochipDIRECT 專線: 07-2137830
Powered by XOOPS © 2001-2012 The XOOPS Project