山本ワールド
加速度センサーADXL345を使用した加速度計
2014/02/22 ソースファイルリンク先修正
2013/10/10 初版
概要
I2C接続の加速度センサーADXL345を使用した加速度をLCD液晶に表示する。
クロックはUSB-IOで接続済みの12MHzのセラミック振動子を使用しPLLで4倍にしている。書込みはPICKit3を前提とする。
液晶表示例
X=+0512 Y=+0234 Z=-0100回路は次のとおりである。
回路図(PNG) 回路図(PDF) 回路図(DXF)
プログラムの説明
ソースファイル
以下のファイルで構成されているg1a.asm ・・・ メインプログラム adxl345.asm ・・・ ADXL345サポートライブラリ Version 1.00 adxl345.inc ・・・ ADXL345サポートライブラリ Version 1.00 i2c.asm ・・・ I2Cサポートライブラリ Version 1.00 i2c.inc ・・・ I2Cサポートライブラリ Version 1.00 lcd.asm ・・・ LCD表示用ライブラリ Version 1.00 lcd.inc ・・・ LCD表示用インクルードファイル Version 1.00 stdlib.asm ・・・ 8bit,16bit割り算、2進,10進,16進数値変換等のライブラリ Version 1.00 stdlib.inc ・・・ 8bit,16bit割り算、2進,10進,16進数値変換等のインクルートファイル Version 1.00
ソースファイルのダウンロード g1a.zip
adxl345.asm
ADXL345の初期化、読み込みをサポート
詳細は以下のリンクを参照されたい
adxl345.asm
i2c.asm
PIC内蔵のI2Cモジュールを使用したI2Cの基本的なプロトコルをサポート
スタート・ストップ・リスタート・1byte書き込み・1byte読み込み・ブロック書き込み・ブロック読み込みをサブルーチン化している。
詳細は以下のリンクを参照されたい
i2c.asm
lcd.asm
主にSC1602向けのLCD液晶表示用のライブラリである。
液晶モジュールと接続するポートはマクロで変更可能である。
busyフラグはチェックせずソフトウェアディレイで対応しているためクロック周波数が変更された場合はディレイの調整が必要
詳細は以下のリンクを参照されたい
lcd.asm
stdlib.asm
8bit,16bit割り算、2進,10進,16進数値変換等をサポートしたライブラリである
詳細は以下のリンクを参照されたいstdlib.asm
g1a.asm
メインプログラムである。
IOポートの入出力の設定・I2Cモジュールの初期化をし、LCDの初期化、ADXL345の初期化、その後、約1秒おきに加速度を取得しLCDに表示する。
; ADXL345を使用した加速度表示 Version 1.00
; File: g1a.asm
; Target: PIC18F14K50 48Mhz
; アセンブラ: Microchip MPASM(v5.51)
; 書き込み: PICKit 3
; リリース: 2013/10/01 21:00
#INCLUDE <p18f14k50.inc>
#INCLUDE "lcd.inc"
#INCLUDE "stdlib.inc"
#INCLUDE "i2c.inc"
#INCLUDE "adxl345.inc"
; 水晶発振(12MHz) クロック分周無 PLL有効(*4)
; ウォッチドッグタイマ無効 低電圧プログラム書き込みモード無効
CONFIG FOSC = HS,CPUDIV = NOCLKDIV,PLLEN=ON,WDTEN=OFF,LVP=OFF
; プログラムメモリadsのアドレスをTLPTRレジスタに上書きする
LDTBLPTR MACRO ads
movlw UPPER ads
movwf TBLPTRU
movlw HIGH ads
movwf TBLPTRH
movlw LOW ads
movwf TBLPTRL
ENDM
bank0 UDATA ; 変数の定義 バンク0 アクセスバンク
Tcount1 RES 1 ; wait
Tcount2 RES 1 ; wait
Tcount3 RES 1 ; wait
LCD_WRITE RES 1 ; writeデータを指定
LCD_TEMP RES 1
Temp1 RES 1 ; サブルーチン用の変数
ARG1 RES 1 ; サブルーチン引数
BYTE2HEX_TEMP RES 1
DIV_A RES 1 ; 除算の被除数を指定 サブルーチンコール後答えが返る
DIV_MOD RES 1 ; サブルーチンコール後余りが返る
DIV_B RES 1 ; 除算の除数を指定
DIV_AL RES 1
DIV_AH RES 1
DIV_MODL RES 1
DIV_MODH RES 1
DIV_COUNT RES 1
LCD_BUF RES 32 ; 16*2文字分のバッファ
ARGL RES 1
ARGH RES 1
GX RES 2 ; 加速度x
GY RES 2 ; 加速度y
GZ RES 2 ; 加速度z
GLOBAL LCD_WRITE,LCD_TEMP,ARG1,ARGL,ARGH
GLOBAL Temp1,BYTE2HEX_TEMP
GLOBAL DIV_A,DIV_MOD,DIV_B,DIV_AL,DIV_AH,DIV_MODL,DIV_MODH,DIV_COUNT
GLOBAL Tcount1,Tcount2,Tcount3
GLOBAL GX,GY,GZ
CODE
ORG 0
goto start ; リセット時
start
clrf ANSEL ; RC3-RC0,RA4をデジタル入力バッファに設定
clrf ANSELH ; RB5-RB4,RC7-RC6をデジタル入力バッファに設定
clrf SLRCON ; PORTA,PORTB,PORTCをスルーレートを標準に設定
clrf TRISA ; PORTAを全部出力に設定
movlw 0f0h
movwf TRISB ; RB7-RB4を入力に設定
clrf TRISC ; PORTCを全部出力に設定する
clrf PORTC ; PORTCを全部0にする。
movlw b'00101000' ; SSPモジュールon,I2Cマスターモード
movwf SSPCON1
clrf SSPCON2
movlw d'116' ; 約100kbps
movwf SSPADD
clrf SSPSTAT
rcall lcd_init ; 液晶初期化
LDTBLPTR lcd_init_str ; マクロでTBLPTRレジスタにlcd_init_strを設定
movlw d'32'
lfsr FSR0,LCD_BUF
rcall prog2mem
rcall adxl345_init
loops
rcall adxl345_gread_xyz
movf GX,W
movwf ARGL
movf GX+1,W
movwf ARGH
lfsr FSR1,LCD_BUF+2
rcall word2sdeg
movf GY,W
movwf ARGL
movf GY+1,W
movwf ARGH
lfsr FSR1,LCD_BUF+d'10'
rcall word2sdeg
movf GZ,W
movwf ARGL
movf GZ+1,W
movwf ARGH
lfsr FSR1,LCD_BUF+d'18'
rcall word2sdeg
lfsr FSR1,LCD_BUF
rcall lcd_disp
rcall wait500
goto loops
prog2mem ; プログラムメモリからデーターメモリへコピーする TABLAT->FSR0
movwf Temp1
prog2mem_loop
tblrd *+ ; プログラムメモリTBLPTRから読み出し後TBLPTRを+1する
movf TABLAT,W
movwf POSTINC0 ; 間接アドレッシング アドレスはアクセス後に+1される
decfsz Temp1 ; Temp1から1を引き結果が0になるまで繰り返す
bra prog2mem_loop
return
wait500 ; 0.5秒Wait
movlw d'50' ; 10ms*50=0.5s
movwf Tcount1
dloop1
movlw d'200' ; 50μs*200=10ms
movwf Tcount2
dloop2 ; t=(12+12*count3)/48MHz 50μs
movlw d'199'
movwf Tcount3
nop
dloop3
decfsz Tcount3
goto dloop3
decfsz Tcount2
goto dloop2
decfsz Tcount1
goto dloop1
return
lcd_init_str
; 0123456789abcdef
DB "X=12345 Y=12345 "
DB "Z=12345 "
END