5

こんにちは、スタックオーバーフローの善良な人々。私の問題は、実行されないように見える割り込みサービス ルーチン (ISR) です。ここに私の設定に関するいくつかの情報があります: 私は avr attiny85 をフラッシュしています。これまでのところ、main.c と 2 つのモジュール (timer と hardwareInit) だけで、プロジェクトの骨組みがセットアップされています。タイマー モジュールには、CTC モードのタイマー 0 を 1 ミリ秒ごとにオーバーフローするように設定するために使用する timer0_init 関数があります。関数は次のとおりです。

void timer0_init( void )
{
    cli();
    TCCR0B |= 3;    //clock select is divided by 64.
    TCCR0A |= 2;    //sets mode to CTC
    OCR0A = 0x7C;   //sets TOP to 124 so the timer will overflow every 1 ms.    
    TIMSK |= 2;     //Enable overflow interrupt
    sei();          //enable global interrupts
}

タイマーを設定して、カウンターがオーバーフローするたびにティックをインクリメントする ISR を追加したので、経過時間などを追跡できます。

ISR(TIMER0_OVF_vect)
{
    cli();
    //ticks ++;
    PORTB |= ( 1 << PORTB0 );   
    sei();
}

ご覧のとおり、動作していないため ticks++ をコメントアウトし、PORTB |= ( 1 << PORTB0 );単純に LED をオンにするものに置き換えました。したがって、割り込みが実行された場合は、LED がオンになっていることを証明することでわかります。
残念ながら、電源を入れることができず、何が欠けているのかわかりません。(1. 正しいピンに LED を設定し、2. 正しいレジスタで正しいビットを操作していることを証明するために、このステートメントだけをPORTB |= ( 1 << PORTB0 );無限ループに入れ、LED が点灯することを確認しました)

詳細については、ここに私の main.c があります。

/*================================= main.c =================================*/

#define F_CPU   8000000UL

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

#include "timer.h"
#include "hardwareInit.h"


int main(){

    //Initialize hardware HERE  
    DDRB |= ( 1 << PORTB0 );    //set this pin as an output for an LED

    SetClockPrescale(1);    //internal clock divided by 1 = 8 MHz, from hardwareInit

    timer0_init();          //set up timer0 for 1 ms overflow


    while(1)
    {
        /* if( getTicks() > 0 )
        {
            PORTB |= ( 1 << PORTB0 );
            _delay_ms(1000);
            PORTB &= ~( 1 << PORTB0 );
            _delay_ms(1000);
        } */

    }
    return 0;
}

したがって、無限ループで表示されるのは私が最初に試したものですが、その後うまくいかなかったので、空のループ (以前のものをコメントアウト) を作成し、割り込みがトリガーされるのを待って、より単純なことを試しました。 LEDをオンにします。

あなたが与えることができるどんな助けでも本当に感謝します. なぜこれが機能していないのか、私はかなり困惑しています。

4

1 に答える 1

9

@andarsが正しく指摘したように、間違ったISRを使用しています。CTC の「比較でタイマーをクリア」モードでは、比較一致でタイマーがクリアされるため、タイマーがオーバーフローすることはありません。

したがって、タイマーの間違った割り込みも有効にしました。TIMSK レジスタのビット 1 は、タイマー 0 のタイマー オーバーフロー割り込みを有効にします。前の理由により、それはトリガーされません。データシートから取得。

ここに画像の説明を入力

OCR0Aコンペア値の設定に 使用しているため、ビット 4 – OCIE0A: Timer/Counter0 Output Compare Match A Interrupt Enableを有効にする必要があります。

ISR に戻ると、TIMSK で設定したビットに応じてISR(TIMER1_COMPA_vect)orが必要になります。ISR(TIMER1_COMPB_vect)比較値も一致するレジスタに書き込む必要があることに注意してOCR0AくださいOCR0B


レジスタ名と同じようにコード内でビット名を使用できることに注意してください。私の意見では、コードがより透過的になります。

対応する割り込みを有効にするには、コードを次のように変更する必要があります。

void timer0_init( void )
{
    cli();          
    TCCR0B |= (1<<CS01) | (1<<CS00);   //clock select is divided by 64.
    TCCR0A |= (1<<WGM01);              //sets mode to CTC
    OCR0A = 0x7C;                      //sets TOP to 124 so the timer will overflow every 1 ms.    
    TIMSK |= (1<<OCIE0A);              //Output Compare Match A Interrupt Enable
    sei();                             //enable global interrupts
}

ISR:

ISR(TIMER0_COMPA_vect)
{
    cli();
    //ticks ++;
    PORTB |= ( 1 << PORTB0 );   
    sei();
}
于 2016-11-20T19:43:52.237 に答える