新會員
Joined
: 2007/7/25 9:55 最後登入時間
: 2007/8/28 11:25
Group:
註冊會員
Level : 1 HP : 0 / 5 MP : 1 / 274 EXP : 21
|
假如我有一個程式如下: 那麼我要修改哪裏讓它可以單純的輸出PWM訊號 且我想要用可變電組來調變DUTY CYCLE 程式如下 #include "p30F4011.h" #define FCY 29491200 // // Fosc = 7.3728 MHz , XT_PLL16 #define PTPERvalue 920 // FPWM = 16 KHz ,[(Fcy/16K)/2]
_FOSC(CSW_FSCM_OFF & XT_PLL16); // XT with 4xPLL oscillator , Failsafe clock off _FWDT(WDT_OFF); // Watchdog timer disabled _FBORPOR(PBOR_OFF & MCLR_EN & PWMxH_ACT_HI & PWMxL_ACT_HI); //Brown-out reset disabled , MCLR reset enabled // _FBORPOR(PBOR_OFF & MCLR_EN & PWMxH_ACT_LO & PWMxL_ACT_LO); //Brown-out reset disabled , MCLR reset enabled , PWM Active Low // _FBORPOR(PBOR_OFF & MCLR_EN); _FGS(CODE_PROT_OFF); //Code protect disabled
void InitMCPWM(void); // Init PWM Module to drive the Inverter void InitADC10(void); // A/D Init Subroutine to Read POT. void InitCN(void); // Change Notification for Hall Effect Sensors
unsigned int HallValue; // Variable containing the Hall Value from PORTB
/************************************************************* Low side driver table is as below. In the StateLoTableClk and the StateLoTableAntiClk tables, the Low side driver is PWM while the high side driver is either on or off. *************************************************************/
unsigned int StateLoTable[] = {0x0300, /* PWM1L -> PWM, PWM1H -> PWM*/ 0x0900, /* PWM1L -> PWM, PWM2H -> PWM*/ 0x0600, /* PWM2L -> PWM, PWM1H -> PWM*/ 0x0C00, /* PWM2L -> PWM, PWM2H -> PWM*/ 0x0600, /* PWM2L -> PWM, PWM1H -> PWM*/ 0x0300, /* PWM1L -> PWM, PWM1H -> PWM*/ 0x0C00, /* PWM2L -> PWM, PWM2H -> PWM*/ 0x0900}; /* PWM1L -> PWM, PWM2H -> PWM*/
/**************************************************************** Interrupt vector for Change Notification CN5, 6 and 7 is as below. When a Hall sensor changes states, an interrupt will be caused which will vector to the routine below. The program then reads PORTB, mask bits 3, 4 and 5, shift and adjust the value to read as 1, 2 ... 6. This value is then used as an offset in the lookup table StateLoTableClk or StateLoTableAntiClk to determine the value loaded in the OCDCON register. *****************************************************************/
void __attribute__((__interrupt__)) _CNInterrupt (void) { TRISDbits.TRISD2=0; LATDbits.LATD2=0; IFS0bits.CNIF = 0; // clear flag HallValue = PORTB & 0x0038; // mask RB3,4 & 5 HallValue = HallValue >> 3; // shift right 3 times OVDCON = StateLoTable[HallValue]; // Energize Transistors from Table LATDbits.LATD2=1; }
/********************************************************************* The ADC interrupt loads the PDCx registers with the demand pot value. This is only done when the motor is running. *********************************************************************/
void __attribute__((__interrupt__)) _ADCInterrupt (void) { TRISDbits.TRISD3=0; LATDbits.LATD3=0; //TRISD = 0xFFF7 ; //LATD = 0x0008 ; IFS0bits.ADIF = 0; // Clear Interrupt Flag PDC1 = (ADCBUF0*0.00097)*1840 ; // get value ... PDC2 = PDC1; // and load all three PWMs ... PDC3 = 0; // duty cycles //LATD = 0x0000 ; LATDbits.LATD3=1;
}
/********************************************************************* main subroutine. It initialized the peripherals used in the application, * Input Change Notifications for Hall effect sensores, * MCPWM module for driving the inverter, * A/D Converter for reading the POT value. When S2 is pressed, the hall effect sensors are read the the corresponding transistors are turned on depending on a look up table. After energizing the first pair of transistors everything else is done in the Change Notification interrupts. *********************************************************************/
int main(void) {
InitCN(); // Init CN for Hall effect sensor inputs InitMCPWM(); // Init PWM for 16 kHz operation InitADC10(); // Init ADC for POT measurement while(1);
} /******************************************************************* Below is the code required to setup the ADC registers for : 1. 1 channel conversion (in this case RB2/AN2) 2. PWM trigger starts conversion 3. Pot is connected to CH0 and RB2 4. Manual Stop Sampling and start converting 5. Manual check of Conversion complete *********************************************************************/
void InitADC10(void) { ADPCFG = 0xFFFD; // all PORTB = Digital ; RB1 = analog ADCON1 = 0x0064; // PWM starts conversion ADCON2 = 0x0000; // simulataneous sample 1 channels ADCHS = 0x0001; // Connect RB1/AN1 as CH0 = pot .. // ch1 = Vbus, Ch2 = Motor, Ch3 = pot ADCON3 = 0x0013; // Tad = 10Tcy Tad>=300ns IFS0bits.ADIF = 0; IEC0bits.ADIE = 1; ADCON1bits.ADON = 1;// turn ADC ON return; }
/******************************************************************** InitMCPWM, intializes the PWM as follows: 1. FPWM = 19531 hz 2. Independant PWMs 3. Control outputs using OVDCON 4. Set Duty Cycle with the ADC value read from pot 5. Set ADC to be triggered by PWM special trigger *********************************************************************/
void InitMCPWM(void) { PTPER = PTPERvalue ; PWMCON1 = 0x0733; // disable PWMs OVDCON = 0x0000; // allow control using OVD PDC1 = 0; // init PWM 1, 2 and 3 to 0%(Duty_cycle) PDC2 = 0; PDC3 = 0; SEVTCMP = 0x0000; PWMCON2 = 0x0F00; // 16 postscale values PTCON = 0x8002 ; // start PWM ; center-mode return; }
/******************************************************************** InitCN, Initializes the Input Change Notification for the Hall Effect Sensors *********************************************************************/
void InitCN(void) { CNEN1 = 0x00E0; // Enable CN5(RB3), CN6(RB4) and CN7(RB5) IFS0bits.CNIF = 0; // clear CNIF IEC0bits.CNIE = 1; // enable CN interrupt return; }
謝謝
發表於: 2007/7/25 10:01
|