Pythonでビット演算子のビットシフトに触れるまでの記事でビット演算に触れてきた。
一通り触れたことで、SPI通信についてを見る準備が出来た。
SPI通信を見る前に、擬似的なUARTのやりとりをビット演算で振り返ってみる。
UARTは上記のようなビット列で、送受信を開始していない時は 1 になっていて、送信を開始した時に スタートビットとして 0 、その後に8ビットの値が続き、必要であればパリティビット、最後にストップビットの 1 になっている。
最初に擬似的にスタートビット + 8ビットで値が 0 のビット列 + パリティビット(奇パリティ) + ストップビットをPythonで再現してみる。
b = 1 print(bin(b)) b <<= 1 # スタートビット print(bin(b)) cnt = 0 # 奇数を集計する for i in range(8): b <<= 1 print(bin(b)) # パリティビット b <<= 1 if cnt % 2 == 1: parityBit = 1 else: parityBit = 0 b |= parityBit print(bin(b)) # ストップビット b <<= 1 b |= 0x1 print(bin(b))
上記のコードを実行してみると、
0b1 0b10 0b100 0b1000 0b10000 0b100000 0b1000000 0b10000000 0b100000000 0b1000000000 0b10000000000 0b100000000001
になった。
最後の行の太文字の 0 の列が、UARTで送信する8ビットの箇所になる。
今回は一つのマシンでの擬似的なUARTになるので、送受信の箇所をランダムにしてみる。
import random b = 1 print(bin(b)) b <<= 1 # スタートビット print(bin(b)) cnt = 0 # 奇数を集計する for i in range(8): b <<= 1 if random.randint(0,1) % 2 == 0: b |= 0x1 cnt += 1 print(bin(b)) # パリティビット b <<= 1 if cnt % 2 == 1: parityBit = 1 else: parityBit = 0 b |= parityBit print(bin(b)) # ストップビット b <<= 1 b |= 0x1 print(bin(b))
上記のコードを実行してみると、
0b1 0b10 0b100 0b1000 0b10000 0b100001 0b1000010 0b10000101 0b100001011 0b1000010110 0b10000101101 0b100001011011
になった。
8ビットの箇所の 1 の個数が奇数なので、パリティ・ビットも効いている。
if random.randint(0,1) % 2 == 0:
実際のコードでは上記の箇所はGPIOでHIGH(1)かLOW(0)の判定になる。
ビット演算をイメージできるようになることで、SPI通信のコードも読めるようになってくる。