2017-04-15 85 views
0

我是AVR C編程新手,我正在用Atmega328p計數器/定時器上的16位定時器測試一個簡單的PWM,它可以用作LED的調光器。16位定時器PWM LED調光器

我的代碼:

#define F_CPU 16000000UL 

void initTimer(); 

int x = 1; 
int n = 1000; 

int main(void) 
{ 

    initTimer(); 

    DDRB |= (1 << PB1)| (1 << PB2); 

    while(1) 
    { 
     x++; 

     if(x > 65) { 
      x = 1; 
     } 
    } 
} 

void initTimer() { 

    TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); 
    TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); 
    // used for TOP, makes for 50 Hz PWM 
    ICR1 = 40000; 
    OCR1A = n * x; 

} 

ISR(TIMER1_OVF_vect) 
{ 
    OCR1A = n * x; 
} 

問題是,它不顯示變暗效果,LED的亮度保持不變,以任何值I爲OCR1A(PB1)的輸出引腳初始設定,其假設當中斷髮生時改變值,但它只是不這樣做,這是假設是簡單的測試我做錯了什麼?

更新:

至於建議,我能夠使用TIMSK1寄存器和SEI(),但仍是同樣的問題,LED的亮度保持恆定的中斷來不管這是在指定OCR1A的原始值initTimer()。

int main(void) 
{ 
    initTimer(); 
    DDRB |= (1 << PB1)| (1 << PB2); 

    while(1) 
    { 
     x++; 
     if(x > 65) { 
      x = 1; 
     } 
    } 
} 

void initTimer() { 

    ICR1 = 40000; 
    OCR1A = n * x; 
    TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); 
    TIMSK1 |= (1 << ICIE1); 
    TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); 
    sei(); 
} 

ISR (TIMER1_COMPA_vect) 
{ 
    OCR1A = n * x; 
} 

雖然我嘗試另一種辦法,這給了我調光影響:

int main(void) 
{ 

    initTimer(); 

    DDRB |= (1 << PB1)| (1 << PB2); 

    while(1) 
    { 
     _delay_ms(20); 
     OCR1A = n * 4; 
     _delay_ms(20); 
     OCR1A = n * 8; 
     _delay_ms(20); 
     OCR1A = n * 15; 
     _delay_ms(20); 
     OCR1A = n * 25; 
     _delay_ms(20); 
     OCR1A = n * 1; 

    } 
} 

void initTimer() { 

    ICR1 = 40000; 
    OCR1A = n * x; 
    TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); 
    TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); 

} 

如此看來問題是與中斷,因爲PWM影響的作品,但它只是沒有與中斷處理工作。

回答

1

跳出來的第一件事是x和n應該是易變的。您還應該在TIMSK0寄存器中啓用中斷。通過調用sei啓用中斷。

如果我是你,我會從一些知道好的示例代碼開始。我提到的頁面有一個例子,每4ms觸發一次中斷。採取該代碼並打開和關閉LED。

另一個問題是你改變x而不考慮isr是否被調用。所以實際上你每次都會在isr中得到一個隨機的x。這段代碼很簡單,可能會陷入簡單模式。而是將x的設置移動到您的isr。

這是一個很好的介紹avr定時器:https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-atmega328