タイマー1 / インプットキャプチャ機能 / パルス幅を測る

pp.496-497

今度は周期ではなくパルス幅を測る。rising edgeをキャプチャしたら次回はfalling edgeをキャプチャし、falling edgeをキャプチャしたら次回はrising edgeをキャプチャして、rising edgeからfalling edgeまでのカウント数を数える。

ISR()はフラグを立てるだけにした。

今10 Hz、デューティ33%のパルスを入力している。
f:id:ti-nspire:20200718133937p:plain:h300 f:id:ti-nspire:20200719111311j:plain:h300

#define F_CPU 8000000UL

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

LCDClass lcd("PD7","PD6","PD5","PD4","PD3","PD2"); // (RS,EN,D4,D5,D6,D7)の順番で指定する。

volatile uint8_t captured = 0;
ISR(TIMER1_CAPT_vect){
    captured = 1;
}

int main(){
    lcd.init();
    lcd.gotoRowCol(1, 1);
    lcd.print("Pulse Width (us)");
    
    // 8分周してカウント。
    TCCR1B |= (1 << CS11);
    
    // インプットキャプチャ割り込みを有効化。
    TIMSK1 |= (1 << ICIE1);
    sei();

    while(1){
        if(captured){
            uint16_t timeRised;
            uint16_t count = ICR1;                // エッジが検出されたらどちらのエッジであろうととにかくカウント値を取得して、
            if(bit_is_set(TCCR1B, ICES1)){        // rising edgeでキャプチャする設定になっていたら、
                timeRised = count;                // rising edgeでのカウント値としてとっておいて、
            }
            else if(bit_is_clear(TCCR1B, ICES1)){ // falling edgeでキャプチャする設定になっていたら、
                lcd.gotoRowCol(2, 1);
                lcd.print(count - timeRised);     // パルス幅を求めて表示して、
            }
            TCCR1B ^= (1 << ICES1);               // 次回はキャプチャエッジを入れ換える。
            captured = 0;
        }
    }
    
    return 0;
}