網頁

2011年4月11日 星期一

DIY - PIC:PIC18F4550 PWM 可調整佔空比程式 (五十六)

DIY - PICPIC18F4550 PWM 可調整佔空比程式 (五十六)

Microchip PIC18F4550 PWM 可調整佔空比程式是利用一個可變電阻來調節, PWM 的佔空比更會改變,佔空比可以調節從 0% 100% (理想值) 。可變電阻器 (10KΩ)是連接到類比數位轉換器 (A/D) 引腳,調節可變電阻器的電阻值,從而改變電壓輸入到類比數位轉換器,類比數位轉換器便將電壓轉化為數值,數值會換算為百份比,這個百份比便是佔空比的數值,佔空比的數值計算計出 CCPRxL: CCPxCON<5:4>的週期數值,便可更改 PWM 的佔空比。

PIC18F4550 PWM 可調整佔空比程式流程圖
 主程式:

void main(void)
{

    // LCD Display         1234567890123456               
    char LCD_name[] ="BWS PWM>>(DC) v1";
    char LCD_name2[]="                ";
   
    // Local Variables

    // Variables for ADC
    float adc0_volt;
    unsigned int adc0_dec;
    unsigned int adc0_100;
    unsigned int adc0_volt1;
    unsigned int adc0_volt2;
    unsigned int float_base=1000;

    // Initialise Port   
    TRISA = 0b00000001;                 // Setup RA0=Input RA1=Output
    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

    // Initialise ADC
    OpenADC(ADC_FOSC_32 &        // A/D clock source set to 32Tosc
            ADC_RIGHT_JUST &            // ADRESH:ADRESL from roght
            ADC_20_TAD,                        // A/D Acquisition time: 20TAD
            ADC_CH0 &                           // Analog Channel0 AN0
            ADC_INT_OFF &                  // ADC Interrupt off
            ADC_VREFPLUS_VDD &    // Vref+ = VDD
            ADC_VREFMINUS_VSS,     // Vref- = VSS
            0b1110                          // ADCON0 = 7 = 00001110=AN0 Analog
             );
   
    //Configure CCP module as (PR2+1)*4*TOSC*T2_PS
    // PWM = 10kHz TMR_PS=1:4 Tosc=20MHz
    PR2     = 124;                           // PWM Frequency = 124 = 10kHz = 0.1ms
    T2CON   = 0b00000110 ;        // 11=1:16 10=1:4 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
   
    while(1)
    {
        ConvertADC();                     // Start an A/D Conversion
        while(BusyADC());               // Wait for Conversion Finished
        adc0_dec=ReadADC();       // Read A/D Result

        // Convert Floating Point to Decimal
        adc0_volt=(float)adc0_dec/1024*5;  // 1024 Step and Vref=5V
        adc0_100 = adc0_dec/10.2;             // Calaculate Percentage %
        LcdSetLine2();                        // Put cursor on start of line 2
        printf("D=%04i=%0.3i%",adc0_dec,adc0_100);

        // CCPRxL:CCPxCON<5:4>*Tosc*TMR2_PS
        CCPR1L = ((PR2+1)*(adc0_100))/100;   // Calaculate Count of Duty Cycle
        printf("=%0.3i",CCPR1L);                         // Display CCPR1L
    } // End While
}

▲紅圈是調整佔空比的可變電阻
▲可變電阻 = 773/1023、佔空比 = 75% CCPR1L = 93
▲佔空比 = 75% (3/4格)
▲可變電阻 = 516/1023、佔空比 = 50% CCPR1L = 62
▲佔空比 = 50% (2/4 格)
2011 04 11 天氣報告
氣溫:22.4 @ 23:00 
相對濕度:百分之81% 
天氣:微雨

2 則留言:

  1. 請問一下 我現在PWM 解析度是8位元 單純是用CCPR1L 所以最大是255
    但發現不夠 想用到10位元 所以想請問CCP1CON<5:4>+CCPR1L 用程式寫的話到底要怎麼表達
    例如 現在程式是

    if (adcbuf>300)
    CCPR1L++;
    else
    CCPR1L--;

    可以怎麼改 感謝~~

    回覆刪除
    回覆
    1. pwm= CCPR1L<<2 + CCP1CONbits.DC1B;

      pwm 是我自訂變數 然後改成 pwm++ pwm-- 但似乎不行

      刪除