7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C言語Advent Calendar 2023

Day 8

Arduinoのレジスタをざっと理解する 後編【ブール代数】

Last updated at Posted at 2023-12-08

情報処理の講義でArduinoのレジスタを触り始めたのですが、解説が絶望的なのでクラスの誰か一人でも救済できたらいいなと思って書いた記事です。

前回のあらすじTL;DR

  • レジスタ操作はただのC言語ゲーミング!!!!
  • ただのdigitalWrite禁止縛り
  • レジスタ変数を操作するとピンを操作できる

詳細はこちら

個別でピンを操作する

前回の

PORTD = 0B01000000;

を改善していきたいと思います。このプログラムはPD6をHIGHに設定するプログラムです。ピンの対応表は前回の記事にもあったこちらの表を参照してください。(DDRをPORTに置き換えてね)

アートボード 2.png

しかしこのプログラム、一部問題があります。PD6以外は全てLOWになってしまいます。対して

digitalWrite(6, HIGH); //6番ピンはPD6

は6をHIGHにしますが6以外は操作しません。これを今回はポート操作で実現していきます。

ビット演算子

ここでビット演算子について復習します。FJT先生のディジタル回路でやったブール代数は理解してる前提で行きます。

&(論理積)

アートボード 4.png

ここでXnはXのn bit目を表すものとします。

論理積はいわゆる掛け算です。元のデータがA、操作をBとした時に以下のように考えるとわかりやすいです。

  • Bが1のところはAが引き継がれる
  • Bが0のところは強制的に0になる

|(論理和)

アートボード 4_1.png

論理和はいわゆる掛け算です。元のデータがA、操作をBとした時に以下のように考えるとわかりやすいです。

  • Bが0のところはAが引き継がれる
  • Bが1のところは強制的に1になる

ビット演算子を用いたレジスタの操作

0→1

「Bが1のところは強制的に1になる」という性質を使いたいので論理和を使います。

PORTD = PORTD | 0B01000000;

こうすると

  • PD6以外はPORTDがそのまま引き継がれる
  • PD6は強制的に1になる

となります。つまり

digitalWrite(6, HIGH); //6番ピンはPD6

と完全に同等です。

1→0

「Bが0のところは強制的に0になる」という性質を使いたいので論理積を使います。

PORTD = PORTD & 0B10111111;

こうすると

  • PD6以外はPORTDがそのまま引き継がれる
  • PD6は強制的に0になる

となります。つまり

digitalWrite(6, LOW); //6番ピンはPD6

と完全に同等です。

省略形

便利なので覚えておきましょう。

PORTD = PORTD | 0B01000000;
PORTD |= 0B01000000;

PORTD = PORTD & 0B10111111;
PORTD &= 0B10111111;

【発展】ド・モルガンの法則

原理を理解してしまえば、あとはブール代数ゲーなのでド・モルガンの法則を適用できます。

論理和

\begin{align}
C &= A + B \\
&= \overline{\overline{A}} + \overline{\overline{B}}\\
&= \overline{\overline{A} ・ \overline{B}}\\
\end{align}

論理積

\begin{align}
C &= A ・ B \\
&= \overline{\overline{A}} ・ \overline{\overline{B}}\\
&= \overline{\overline{A} + \overline{B}}\\
\end{align}

まぁそれはそうって感じですね。これを使ってさっきの式を書き換えると、

PORTD = PORTD | 0B01000000;
PORTD = ~(~PORTD & 0B10111111);
PORTD = PORTD & 0B10111111;
PORTD = ~(~PORTD | 0B01000000);

です。~は反転の記号です。

まぁこれくらい覚えておけばEND先生に煽られることはないと思います。

ビットシフト

シフト演算子を思い出してください。これらはそれぞれ同様です。

PORTX |= 0B01000000;
PORTX |= 0B1 << 6;
PORTX &= 0B10111111;
PORTX &= ~(0B1 << 6);

補足すると、論理和の方は0B00000001をシフトした後に反転しています。

チートシート

最悪これ覚えておけばおk

PORTX |= 0B01000000; // 0→1
PORTX |= 0B1 << 6;   // 0→1
PORTX &= 0B10111111; // 1→0
PORTX &= ~(0B1 << 6);// 1→0

DDRXについても同様です。

おわりに

おわりです

7
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?