2011年4月20日 星期三

DIY - PIC:PIC18F4550 PWM 正弦波程式 (六十一)

DIY - PICPIC18F4550 PWM 正弦波程式 (十一)

Microchip PIC18F4550 PWM可調整佔空比變成正弦波程式,程式主要利用預先設定的一系統的數值,產生一連串的PWM及不同的佔空比值訊號,然後通過低通濾波器 (LPF) 的電子線路,輸出組合一連串的PWM的訊號,便會變成正弦波。

PWM正弦波程式流程圖

程式:
const rom char waveform[64] = {
127, 139, 152, 164, 176, 187, 198, 208,
217, 225, 233, 239, 244, 249, 252, 253,
254, 253, 252, 249, 244, 239, 233, 225,
217, 208, 198, 187, 176, 164, 152, 139,
127, 115, 102,  90,  78,  67,  56,  46,
 37,  29,  21,  15,  10,   5,   2,   1,
  0,   1,   2,   5,  10,  15,  21,  29,
 37,  46,  56,  67,  78,  90, 102, 115}; // Sinewave lookup-table

void main(void)
{

    //                1234567890123456               
    char LCD_name[] ="BWS PWM->SINE v1";
    char LCD_name2[]="                ";
  
    ADCON0 = 0x00;             // Disable the AD converter
    ADCON1 = 0x0F;             // Set all ports to digital
    TRISB  = 0b11100000;     // Set PORTB RB5 as Key In
    TRISC  = 0b11111001;     // Set PORTC C1 and C2 as PWM output
    LATC   = 0b00000000;     // Clear PORTC   
   
    // Initialise LCD
    OpenXLCD(FOUR_BIT&LINES_5X7);    // Init the LCD Display
    while(BusyXLCD());
    WriteCmdXLCD(BLINK_OFF & CURSOR_OFF ); 
    while(BusyXLCD());    
    stdout = _H_USER;                // Redirect I/O to LCD
    LcdSetLine1();                        // Put cursor on start of line 1
    putsXLCD(LCD_name);         // Display text

    //Configure CCP module as (PR2+1)*4*TOSC*T2_PS
    PR2     = 0b10011011;           // PWM Frequency = 152 = 2KHz = 0.5ms
    T2CON   = 0b00000100 ;      // 11=1:16 00=1:1
    CCP1CON = 0b00001100 ;  // PWM Mode P1A/P1C/P1B/P1D=H <5:4> DC
    CCP2CON = 0b00111100 ;  // PWM Mode P2A/P2C/P2B/P2D=H
                                                   // Duty Cycle CCP1CON<5:4>+CCPR1L
   
    RCONbits.IPEN   = 0;     // Interrupt Priority Control: OFF
                                            // (RCON register IPEN bit = 0)
    PIE1bits.TMR2IE = 1;     // Timer2 interrupt enable
    INTCONbits.PEIE = 1;   // peripheral interrupt enable
    // INTCON register bit b6: low interrupt enable / disable
    // (When interrupt priority control)
    INTCONbits.GIE  = 1;    // all interrupt enable
    // INTCON register bit b7: high interrupt enable / disable
    // (When interrupt priority control)

    while(1)
    {

    } // End While
}


void high_isr (void)
{
    PIR1bits.TMR2IF = 0;    // Timer2 interrupt flag to 0
    CCPR1L = waveform[wave];
    CCPR2L = waveform[wave];
    wave++;
    if (wave > 64) wave=0;
}


PWM及低通濾波器輸出連接至示波器

▲蠻像正弦波
▲放大後,正弦波的上半部有點失真
▲再放大後,可見PWM 有不同的佔空比及正弦波的上昇下降波型


在業餘的實驗結果是可接受,如果要將正弦波的波型達到完美,需要調整 Table內的數值及低通濾波器 (LPF) 的電子線路。

2011 04 20 天氣報告
氣溫:22.3 @ 23:00 
相對濕度:百分之82% 
天氣:大致多雲

沒有留言:

張貼留言