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