2017-04-15 6 views
0

私はAVR Cプログラミングの初心者です。私は、LEDの調光器として機能すると思われるAtmega328pカウンタ/タイマの16ビットタイマを使用して簡単なPWMをテストしています。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の明るさは、私が最初にOCR1A(PB1)出力端子に設定されたどのような値、その考えるのような一定のまま割り込みが発生したときに値を変更するには、これをやっていないだけですが、これは簡単なテストであると思います。

更新:アドバイスとして

Iは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のオンとオフを切り替えます。

もう1つの問題は、isrが呼び出されたかどうかにかかわらずxを変更していることです。したがって、実際には、isrで毎回ランダムxが得られます。このコードはシンプルであり、単純なパターンで詰まる可能性があります。代わりに、xの設定を自分のisrに移動します。

ここには、avrタイマーの良い紹介があります:https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-atmega328

関連する問題