3軸加速度センサ(ADXL345)をSPIで接続してみます
〔PICの動かせ方入門に戻る〕
前回の記事で3軸加速度センサ(ADXL345)とPIC16F1827をI2Cにて接続し傾斜角度を表示する実験を
行って見ました。
ADXL345はSPIでも接続する事が出来るので、今回はこのセンサとPIC12F1822をSPIで接続して
センサ出力値を表示させて見たいと思います。
12F1822では傾斜角度の表示は浮動小数点(float)を扱うのでプログラムメモリ容量が足りなくなります。
よってここではセンサ値の表示のみ実験します。
尚、ADXL345の話とSPI接続でも傾斜角度を表示させたい場合は16F1827辺りを使用して前回の記事
を参考にして下さい。
《配線図》
左図はPIC12F1822のピン構成図です。
今回使用するピンは、
電源ピンの1番(VDD)と8番(VSS)に、
SPIピンの5番(SDI)と6番(SCK)で、
SDOは3番か7番ですが今回は3番です、
また、SS(CS)ピンは2番(RA5)から出力です
電源はセンサが3.3Vなので回路も3.3V電源で統一しています。
尚、データ表示用に7番(RA0)ピンから出力し、別途作成した自作のLCDモニターに表示させています。
このLCDモニターは5V電源なので別電源を用意し3.3Vと5VのGND同しは接続しています、
3.3V電源LCDを持っている人はそれを利用しても良いでしょう。
4番ピン以外は全ピン使用しています、またメモリ容量の関係からも16F1827辺りで実験を行う事を
推奨します。(今回は12F1822でのご要望があったので使用しました)
左が実態配線図で下がセンサモジュールのピン構成図です。
センサピンの使い方等のデータシートは、こちらのHPから
ダウンロードして下さい。
尚、センサのCSピンをVDDに配線するとI2C駆動になりますが、
PICからLOWにして通信を行うとSPI駆動になる様です。
《ダウンロードプログラムについて》
↓ここからサンプルプログラムソースファイルをダウンロードして下さい。
ADXL345SPI.lzh(Ver1.00:2014/3/29)
ADXL345SPI.lzh(2014/9/27 skSPIlib.cを変更) *1)
ADXL345SPI.lzh(2015/10/14 MPLAB X/XC8(V1.32)に対応 *2)
ADXL345SPI.lzh(skSPIlibを変更) *3)
プログラムソースをダウンロードしたら、MPLAB X(v2.15)にてプロジェクトを作成します。
以下のファイルをプロジェクトディレクトリにコピーしてプロジェクトに取込んで下さい。
次にコンパイルとPIC書き込みを実行して下さい。 *2)
MPLAB(R) XC8 C Compiler Version 1.32コンパイラを使用しています。
ダウンロードしたら解凍して下さい、以下のファイル構成です。 *2)
acceler1.c・・・・・・・・・本体のサンプルソースプログラム1(各軸読込み値表示用)
skADXL345SPI.c・・・ADXL345関数ライブラリソースファイル(SPI用) *3)
skADXL345SPI.h・・・ADXL345ライブラリ用ヘッダファイル(SPI用)
skSPIlib.c・・・・・・・・・・SPI通信を行う関数ソースファイル *3)
skSPIlib.h・・・・・・・・・・SPI通信を行う関数のヘッダファイル *3)
このプログラムにはデバッグモニタープログラム「skMonitorLCD.c」「skMonitorLCD.h」が必要です。
デバッグLCDモニターについてはこちらを参照して下さい。
また、LCDモニターの出力はRA0から行っているので「skMonitorLCD.h」を下記の様に変更します。
#define _XTAL_FREQ 8000000 // 使用するPIC等により動作周波数値を設定する
#define BAUDRATE 51 // 9600bps(8MHz=51)(4MHz=25)(16MHz=103)(20MHz=129)
#define MONITOR_PIN RA0 // モニタ出力するピンの番号を設定する
ここの実験はPICのシステムクロック 8MHzでの実験となっています。
acceler1.c
このサンプルプログラムは、センサが出力するそのままの値を、各軸100回読み込んで単純平均化
させた値を表示させる物です。
このセンサにはFIFO型バッファ機能が有るのでこれをうまく利用すれば移動平均などを行わせる事が
出来ると思うのですがぁ....
左写真は、センサが水平時の値で、表示2行目の左側がX軸で、
中央がY軸、右側がZ軸です。
XY軸は0gでZ軸は1gでの内容です。
(センサにより値は変わります)
センサを動かせば表示が変わると思います。
skADXL345SPI.h
ADXL345にSPIでアクセスする為のライブラリ用のヘッダファイルです。
"skADXL345SPI.c"を利用する場合に
#include "skADXL345SPI.h" をプログラムの先頭で記述して下さい。
今回は8MHzで利用しているので、
#ifndef _XTAL_FREQ
// Unless already defined assume 8MHz system frequency
// This definition is required to calibrate __delay_us() and __delay_ms()
#define _XTAL_FREQ 8000000 // 使用するPIC等により動作周波数値を設定する
#endif
と記述しています、8MHz以外で利用する人は"8000000"を書き換えて下さい。
SPIのピン指定について
PIC側のSPIで使用するピンを下記の様に記述しています、変える場合は変更しましょう。
尚、ADXL345_SDOはPIC端子の番号で指定し、ADXL345_CSはPIC端子のデジタルピン名称で指定です、間違わない様にしましょう。
#define ADXL345_SDO 3 // ADXL345と接続するPIC側のSDOピン番号を設定する
#define ADXL345_CS RA5 // ADXL345と接続するPIC側のCSピン名称を設定する
skADXL345SPI.c
このライブラリはADXL345を使った3軸加速度センサモジュールにSPIでアクセスする為の関数集です。
センサには色々な機能が有るのですが、このライブラリは各軸の値を読み込む機能のみ対応です。
その他の機能についてはいずれ試そうと思いますが....いつになるやら...
この関数集にはskSPIlib.c/skSPIlib.hのファイルが必要です。
また、この関数集自体は他のPICでも利用可能でしょう。
ADXL345にアクセスを行う関数の使い方を説明します。
ans = acceler_Init( )
ADXL345の初期化を行う処理です。
分解能は10bitモードで出力、使用するレンジは±2Gで出力データレートは800Hz、
またFIFOは使用しないで初期化しています。
ans : -1ならADXL345が応答していない、正常ならADXL345のID(0xE5)が返ります。
ans = acceler_Read(*X,*Y,*Z)
ADXL345の各軸の値を読み込む処理です。
XYZ軸のセンサ値を読み込んで指定の変数にデータを返します、大体±300内位の値です。
*X : X軸の値を読み込みこの変数にデータを設定
*Y : Y軸の値を読み込みこの変数にデータを設定
*Z : Z軸の値を読み込みこの変数にデータを設定
ans : 0=正常(I2Cの場合と統一する為に0を返すだけです)
例)
int X , Y , Z , ans ;
ans = acceler_Read(&X,&Y,&Z) ;
if (ans == 0) {
// 各軸の表示を行うなどの処理を行う
}
skSPIlib.h
SPI通信を行う関数のヘッダファイルです。
"skSPIlib.c"を利用する場合に
#include "skSPIlib.h" をプログラムの先頭で記述して下さい。
デフォルトではMSSP1を使う様になりますが、PICによってはMSSP2が有ります。
MSSP2側を使う場合は、"#define SPI_MSSP2_USE"を記述して下さい。 *2)
skSPIlib.c
このライブラリはSPI通信を行う為の関数集です。
この関数集は、PIC12F1822/PIC16F18xx/193x/PIC18F2xK22で使用出来ます。 *2)
SPI通信を行う関数の使い方を説明します。
InterSPI( )
SPI受信関連の割り込み処理
この関数はメインプログラムの割込み関数で必ず呼びます。 *1)
SPI_Init(mode,divider,sdo)
SPIモードの設定と初期化を行う処理
mode :SPIの転送モードを設定します(クロック極性とクロック位相の組み合わせ) *3)
SPI_MODE1 = クロック極性(0:LOW) クロック位相(0:アイドル0Vで、0V->5Vに変化で転送)
SPI_MODE0 = クロック極性(0:LOW) クロック位相(1:アイドル0Vで、5V->0Vに変化で転送)
SPI_MODE3 = クロック極性(1:HIGH) クロック位相(0:アイドル5Vで、5V->0Vに変化で転送)
SPI_MODE2 = クロック極性(1:HIGH) クロック位相(1:アイドル5Vで、0V->5Vに変化で転送)
divider :SPIの通信速度を設定します
SPI_CLOCK_DIV4 = Fosc/4 (PIC動作周波数の4分の1で動作)
SPI_CLOCK_DIV16 = Fosc/16 (PIC動作周波数の16分の1で動作)
SPI_CLOCK_DIV64 = Fosc/64 (PIC動作周波数の64分の1で動作)
SPI_CLOCK_DIVT2 = TMR2の出力の1/2 (タイマー2の速度で動作)
SPI_CLOCK_DIVADD = FOSC / ((SSPxADD + 1) * 4)
sdo :使用するSDO送信のピン番号を指定する
SPI_setDataMode(mode) *2)
SPIの転送モード設定を行う処理
mode :SPIの転送モードを設定します(上記参照)
SPI_setClockDivider(divider,rate) *2)
SPIの通信速度設定を行う処理
divider :SPIの通信速度を設定します(上記参照)
rate :SSPxADDに設定するクロック分周値(SPI_CLOCK_DIVADDを指定する場合に設定する値)
SPI_CLOCK_DIVADD = FOSC / ((SSPxADD + 1) * 4)
rate=0は指定不可です、”SPI_CLOCK_DIV4”を使いましょう。
ans = SPI_transfer(dt)
SPI通信でのデータ送信とデータ受信を行う処理
dt : 8ビットの送信するデータを指定します
ans: 8ビットの受信したデータを返します
《その他》
左は実験風景です。
このセンサは、タップ/ダブル・タップ機能や
自由落下機能にFIFO型バッファ内蔵など
色々機能を持っていますが、今回は利用して
いないのでその内にでも実験をして見ようとは
思っていますがぁ.....
I2Cバージョンでコンパイルした場合は、
Program space=70.0%でしたが、SPI時は62.1%
となりました。
SPIのメリットはプログラム容量が少ない事と、
通信速度が速いと言う所でしょうか。
デメリットは接続線数がI2Cは2本、SPIは4本、
しかもSPIのデバイスを増やす毎に1本づつ
増えて行きます。
"skSPIlib"のSPI_MODEのCKE(クロック位相)を変更(*3) 2016/06/16
MPLAB X用に記事変更(*2) 2015/10/14
"skSPIlib.c"を変更(*1) 2014/09/27
【きむ茶工房ガレージハウス】
Copyright (C) 2006-2016 Shigehiro Kimura All Rights Reserved.