micro:bit に入力したパルスのパルス幅を測る / GPIO の IN レジスタの変化をポーリング方式で直接読み取る

#include "MicroBit.h"
MicroBit uBit;

int main(void){
    
    // IN レジスタからは、各 GPIO ラインへの入力信号が H (1) なのか L (0) なのかが読み出せる。
    // PIN_CNF[N] レジスタは、特定の GPIO ラインの状態が設定できる。
    volatile unsigned int *IN        = (unsigned int *)(0x50000000UL + 0x510);
    volatile unsigned int *PIN_CNF_3 = (unsigned int *)(0x50000000UL + 0x70C);
    
    // エッジコネクターの P0 端子 (GPIO_P3) にパルスを入力することにする。
    // GPIO_P3 の状態を設定する PIN_CNF_3 レジスタの全部のビット 0 に設定する。
    // すなわち GPIO_P3 は「入力端子として設定」「入力バッファーを接続」に設定される。
    unsigned int EdgeP0 = 1 << 3;
    *PIN_CNF_3 = 0x0;
    
    volatile int i;
    while(1){
        while(EdgeP0 == ((*IN) & EdgeP0)){} // 入力パルスが H の途中であるといけないので一旦注目ビットが 0 になるまで待つ。
        while(EdgeP0 != ((*IN) & EdgeP0)){} // 注目ビットに 1 が立つまで待って、
        for(i = 0; i < 5000; i++){          // 注目ビットに 1 が立ったらループ回数のカウントを始めて、
            if(EdgeP0 != ((*IN) & EdgeP0)){ // 注目ビットが 0 になったら
                break;                      // ループ回数のカウントを終えて、
            }
        }
        printf("%d\n", i);                  // カウントしたループ回数を返す。
    }
}

実行結果:
横軸がパルス幅〔マイクロ秒〕、縦軸がループ回数。
f:id:ti-nspire:20180523155629p:plain:w500