ラズパイでSPI通信に挑戦!①(C言語)

ラズパイでSPI通信に挑戦!①(C言語) RaspberryPi
スポンサーリンク

こんにちは!駆け出しエンジニアのまっきーです。

今回はA/Dコンバータ(MCP3008)を使って、SPI通信の学習をしていきます。

だんだん、本格的になってきました。(個人的にですが笑)

この記事では、SPI通信、AD変換の説明、自分なりにデータシートを読み解きます。

実際に動作させるのは次回になります。

SPI通信とは

シリアル・ペリフェラル・インタフェース(Serial Peripheral Interface, SPI)は、コンピュータ内部で使われるデバイス同士を接続するバスである。パラレルバスに比べて接続端子数が少なくて済むシリアルバスの一種で、比較的低速なデータ転送を行うデバイスに利用される。(wikipedia)

このように、SPIはマイコンと周辺ICの間でよく使われる、同期式/全二重のマスタ‐スレーブ型インターフェースです。A/DコンバータやD/Aコンバータなどで主に使用されています。

信号線は4本あり、各名称は以下のようになります。

SCK(Serial Clock)クロック信号

MOSI(Master Out Slave In)マスターの受信信号

MISO(Master In Slave Out)マスターの送信信号

SS(Slave Select)スレーブセレクト信号

また、マスター側のスレーブセレクトを増やすことで複数のデバイスとも接続ができます。

A/D変換とは

A/D変換とは、名前の通り、アナログ値(連続したデータ)をデジタル値(不連続なデータ)に変換することをいいます。

このアナログからデジタル値へ変換する機能を持つICをADC(A/Dコンバータ)といいます。

*IC 回路素子をひとつのパッケージとしてまとめた回路のこと

下のグラフはアナログ信号(入力)とデジタル信号(出力)の関係を示したものです。デジタル信号の差として判別できるアナログ信号の最小振幅が最小分解能(=1LSB)であり、アナログ信号とデジタル信号の間で生じる誤差を量子化誤差といいます。

また、最初のデジタル信号変化点(000→001)の0.5LSB下をゼロスケール、最後のデジタル信号変化点(110→111)の0.5LSB上をフルスケール、ゼロスケールからフルスケールの間隔をフルスケールレンジといいます。

(引用元https://www.rohm.co.jp/electronics-basics/ad-converters/ad_what2

このように量子化を行った際、誤差が生じます。これは必ず発生するものと考えて良いようです。
また、ADCの方式には、並列比較方式、逐次比較方式、二重積分法式、デルタシグマ方式など様々な方法があるようです。まだまだ理解していないので、今回は逐次比較方式のみ、「データーシートを読み解く」のところで触れていきたいと思います。

データシートを読み解く

では、データシートを確認していきたいと思います。

今回使用するADCはMCP3008というスターターキットに付属していたものです。

Amazon.co.jp: OSOYOO(オソヨー) Raspberry Pi 学ぶ電子工作キット 初心者演習用パーツセット ラズパイ11実例 回路配線図とサンプルスケッチ有り プログラミング ラズベリー パイ 超入門 スターター学習キット LED制御 スイッチ I2C LCD 温湿度センサー マイクロサーボ 人体感知センサー A/Dコンバータ ブザー 大気圧センサー リレーモジュール制御 赤外線リモコン等IoTを実践する電子部品セット (Pi 3 DIY Kit 22in1): ホビー
Amazon.co.jp: OSOYOO(オソヨー) Raspberry Pi 学ぶ電子工作キット 初心者演習用パーツセット ラズパイ11実例 回路配線図とサンプルスケッチ有り プログラミング ラズベリー パイ 超入門 スターター学習キット LED制御 スイッチ I2C LCD 温湿度センサー マイクロサーボ 人体感知...

まず、MCP3008の基本的な仕様です。

  • 電源電圧2.7V~5.5V
  • 入力チャンネル8チャンネル
  • サンプリング速度200 ksps
  • クロック 最大3.6MHz
  • 10bit分解能

逐次比較方式

逐次比較方式の流れを簡単に説明します。

ブロック図

データシートより)

①サンプル&ホールド回路でアナログ信号を一時的に格納する

②SAR(逐次比較レジスタ)の最上位ビット(MSB)を1にセットする

③コンパレータでDACと入力されたアナログ信号を比較する

④入力信号の方が大きければMSBは1、小さければ0にする。

⑤MSB-1のビットを1にしてLSBまで③と④を繰り返すことによってデジタルデータを取得できる。

サンプル&ホールド回路で保持→比較を繰り返すことから逐次比較といわれるのですね。

参考https://ednjapan.com/edn/articles/1309/24/news006.html

これは、MCP3008 のピン配置です。以下、各名称を説明します。

VDD 電源電圧

VREF (Reference Voltage Input)基準電圧

AGND アナロググラウンド(ノイズを減らすためブレッドボードの方で接続)

CLK シリアルクロック

DOUT シリアルデータ出力(SPIバスのMISOと接続)

DIN シリアルデータ入力(SPIバスのMOSIと接続)

CS・SHDN チップセレクト/シャットダウン(LOWの時に有効になる)

DGND デジタルグラウンド(ノイズを減らすためブレッドボードの方で接続)

CH0~7 8個のアナログチャンネル これらにセンサー等を接続する

DINとDOUTの接続に注意が必要です。MOSI(INなのでDIN)、MISOOUTなのでDOUT)と覚えておけばいいですね。

最後に、一番重要なタイミングチャートです。ここはとても苦手です。

ですが何とか、理解できました!

前提として、2つの通信方法があります。以下の図を見てください。

左が連続したクロックで通信を行う方法

右が8ビットセグメントごとに通信を行う方法です

ラズパイでは右の通信を行うそうです。

ですが、せっかくなので、両方のタイミングチャートをしっかり見ていくことにします。

連続した通信

①CSをLOWにして動作を有効にする

②DINにコマンドをライトする

 Startビット=1

 SGL/DIFF(Single or differential)

 Single = 1 8チャンネルがアナログ入力となる方式

 Differential = 0 2チャンネル間の作動変換方式

 D2,D1,D0のチャンネル表は下の表を参考に

③CLKの立ち上がりで命令がライトされる

④t sample の区間でA/D変換が行われる

⑤t sample 終了後LOW(NullBit=0)になる

⑥完了後、HIGHに戻る

例えば、3チャンネル指定のシングルエンド方式を用いる場合

Start =1

SGL/DIFF = 1

D2 = 0

D3,D4 = 1

と設定します。

*シングルエンド方式

グラウンド(0V)を基準に信号の電圧レベルで“L”と“H”が決まる方式のこと

8bitセグメントの通信

下の図のようにSCLK(クロック通信)で8ビット*3のバッファが必要ということがわかると思います。

赤枠のDIN,DOUTでデータのやり取りをするのですが、その中身が下の2つの表です。プログラムを書く際に、とても重要になってくる部分ですので、忘れないようにしましょう!

これはCH3(チャンネル3)を使用すると仮定した設定です。

終わりに

なんとなくでも、通信のイメージはしていただけたでしょうか?

ADCのようなICを使用するのが初めてで戸惑った部分も多かったですが、様々な方のサイトや、書籍を参考に何とか理解できました。(もし違ってたら教えてください)

(参考書籍 C言語で始める RaspberryPi徹底入門)

では、次回は実際にADCを使用していきたいと思います。

タイトルとURLをコピーしました