0

Atmega128 の pwm コードを書きました。比較一致で非反転パルスを使用する高速 pwm モードを使用していますが、特定の時間に OCR0 の値を変更する必要があります。それでも変わらない。ここで何が問題なのか誰でも知っていますか??

#include <avr/interrupt.h>
#include <avr/io.h>



uint8_t tick_1sec;



void timer1_init(void) // 1 second timer
{
    OCR1A = 15624;

    TIMSK |= (1<<OCIE1A);
    TCCR1B = (1<<WGM12);        //CTC mode
    TCCR1B |= (1<<CS12)|(0<<CS11)|(1<<CS10);    
}



ISR(TIMER1_COMPA_vect)  //1 second interrupt
{
    cli();
    tick_1sec = 1;
    sei();          
}



void timer0_init(void) // fast pwm with OC0 non-inverting mode
{
    TCCR0 = (1<<FOC0)|(1<<WGM01)|(1<<WGM00);
    TCCR0 |= (1<<COM01)|(0<<COM00);
    TCCR0 |= (1<<CS02)|(1<<CS01)|(1<<CS00);
    OCR0 = 63;
    TIMSK |= (1<<OCIE0);
}



int main(void)
{
    uint8_t t = 0;

    DDRB = 0xFF;

    timer0_init();      
    timer1_init();
    sei();

    while(1){

        if (tick_1sec)
        {
            tick_1sec = 0;
            t++;
            if (t == 10){
                OCR0 = 127;
            }
            else if (t == 20){
                OCR0 = 191;
            }
            else if (t == 30){
                OCR0 = 63;
                t = 0;
            }
        }
    }

    return 0;
}
4

1 に答える 1

2

確認事項:

コンパイラーがそのレジスターを過度に最適化するのを防ぐために、tick_1secasを宣言することをお勧めします。volatile

クロック周波数は?ISR は、CPU 周波数が 16MHz (==> 16.000.000 / 1024 / 15624) の場合にのみ 1 秒の呼び出しを配信します。

ハードウェアに LED があり、a) からISRb) を最初if ()に反転して、mainこれに到達したかどうかを確認できます。

更新:「揮発性」

@skyrift のコメントで提供されたリンクは、読む価値があります。

Atmel Studio を使用する場合は、volatileキーワードを使用して/使用せずにコードを 1 回コンパイルし、コンパイラーの動作を比較します ==> ソリューション エクスプローラー / 出力ファイル / *.lss ... 各 C ステートメントと、コンパイラーがそれをどのように変換するかを確認します。マシンコード ... マイクロを扱う際に時々行う価値のある演習 ...

于 2014-01-21T18:18:30.643 に答える