// Period Calculation // Period = TMRClock * 6 / RPM // For example> // RPM = 6000 (Max Speed) // Period = (20,000,000 / 64) * 6 / 6000 = 312.5 // RPM = 60 (Min Speed) // Period = (20,000,000 / 64) * 6 / 60 = 31250 這程式設定最高6000rpm最低也不到60 可是接24V BLDC 實際測出的轉速為3000rpm最低為264rpm 上面的定義是不是有問題? #define MINPERIOD 313 // For 6000 max rpm and 10 poles motor #define MAXPERIOD 31250 // For 60 min rpm and 10 poles motor #define MINABSSPEED 327 #define MAXABSSPEED 32663 #define SFloat_To_SFrac16(Float_Value) (((Float_Value) < 0.0) ? (SFRAC16)(32767 * (Float_Value) - 0.5) : (SFRAC16)(32768 * (Float_Value) + 0.5)) //這一行要更動嗎? void __attribute__((__interrupt__)) _ADCInterrupt (void) { IFS0bits.ADIF = 0; RefSpeed = (int)(((unsigned int)ADCBUF0) / 2); //The A/D is using unsigned fraction format. //Please refer to the user manual too see the detail. //In this mode, the max A/D is around 65535 which is almost “2” for Q15 format. The PID loop is using Q15 format so the A/D need to be divided by 2 to fit the max limit which is 32767. if (RefSpeed < 2000) RefSpeed = 2000; //Q15(2000) = 2000/32768 = 0.061 6000 RPM a 1 0.061*6000RPM = 366 RPM
return; }
void SixStepComm (int _Sector, int _Voltage) {
if (_Voltage >= 0) {
PDC1 = PDC2 = PDC3 = (unsigned int)_Voltage / 16; //The Voltage is also Q15 format in which the maximum is 32767. //So divided by 16 is to fit the PDC max value. if (_Sector == -1) OVDCON = 0x0000; else OVDCON = StateLoTable[_Sector]; } else { PDC1 = PDC2 = PDC3 = (unsigned int)(-(_Voltage+1)) / 16; if (_Sector == -1) OVDCON = 0x0000; else OVDCON = StateLoTable[(_Sector + 3) % 6]; } return;
我更改為 //馬達為8級 //MINPERIOD 最大轉速設定為2500rpm //(Timer 1 時脈) x 60/(最大轉速2500rpm) x (馬達級數)=(20,000,000/64)*60/[(2500rpm)*8]=938 //MAXPERIOD 最小轉速設定為150rpm //(Timer 1 時脈) x 60/(最小轉速150rpm) x (馬達級數)=(20,000,000/64)*60/[(150rpm)x8]=15625
PDC1 = PDC2 = PDC3 = (unsigned int)_Voltage / 16; //The Voltage is also Q15 format in which the maximum is 32767. //So divided by 16 is to fit the PDC max value. if (_Sector == -1) OVDCON = 0x0000; else OVDCON = StateLoTable[_Sector]; } else { PDC1 = PDC2 = PDC3 = (unsigned int)(-(_Voltage+1)) / 16; if (_Sector == -1) OVDCON = 0x0000; else OVDCON = StateLoTable[(_Sector + 3) % 6]; } return;