micro:bit / マイコンの内部レジスタを操作する / 何かを書き込む / 2 つの端子から同じタイミングで反転パルスを出力する
今度は、反転したパルスを 2 つの端子から同時に出力してみる。
OUTSET レジスタと OUTCLR レジスタとを使えば、複数のビットを同時に H にすること、複数のビットを同時に L にすることができるが、複数のビットの一部だけを H に、一部だけを L に同時に設定することはできない。
OUT レジスタを使えば 32 ビットの全部を個別に H にも L にも設定できる。目的のビットだけを設定してそれ以外は変化させたくないときは、目的のビットだけ 1 にしたデータと OUT レジスタ との XOR を取ればよい。
int main(void){ unsigned int BaseAddress = 0x50000000UL; // GPIO の各種レジスタのベースアドレス // OUT は全ビットの H 出力、L 出力を全部一度に設定するレジスタ // OUTSET は指定のビットだけを H に設定するレジスタ (指定していないビットは変化しない) // OUTCLR は指定のビットだけを L に設定するレジスタ (指定していないビットは変化しない) // DIRSET は指定のビットだけを出力に設定するレジスタ (指定していないビットは変化しない) volatile unsigned int *OUT = (unsigned int *)(BaseAddress + 0x504); volatile unsigned int *OUTSET = (unsigned int *)(BaseAddress + 0x508); volatile unsigned int *OUTCLR = (unsigned int *)(BaseAddress + 0x50C); volatile unsigned int *DIRSET = (unsigned int *)(BaseAddress + 0x518); // エッジコネクターの P0 (GPIO_P03) と P1 (GPIO_P02) とを出力に設定する。 unsigned int EdgeP0 = 1 << 3; unsigned int EdgeP1 = 1 << 2; unsigned int whichBits = EdgeP0 | EdgeP1; *DIRSET = whichBits; // 最初に P0 と P1 とのロジックを逆にしておく。 *OUTSET = EdgeP0; *OUTCLR = EdgeP1; while(1){ // ループを繰り返すたびに、OUT レジスタの特定のビット (エッジコネクターの P0、P1) だけを反転する。 *OUT ^= whichBits; } return 0; }
実行結果:
反転したパルスがまったく同じタイミングで出力されている。
この方法だと、1 回のループで 1 回だけオン、オフが切り換わるのでデューティーは 50% になる。
――――――――――――――――――――――――――――――――――――――――――――