概要

LCD液晶に約0.5秒おきに0から65535までを10進数,16進数,2進数で表示する。
LCD液晶はSC1602を対象としているが、液晶モジュールの電源の接続をVDD,GNDを入れ替えればSC2004でも対応可能。ただし16文字*2行でしか表示されないので注意。
約0.5秒の時間はソフトウェアによるディレイ(クロック周波数に依存)で対応。
クロックはUSB-IOで接続済みの12MHzのセラミック振動子を使用しPLLで4倍にしている。書込みはPICKit3を前提とする。
液晶表示例

65535   FFFF
1111111111111111
回路は次のとおりである。
回路図(PNG) 回路図(PDF) 回路図(DXF)

プログラムの説明

ソースファイル

以下のファイルで構成されている
lcd1a.asm ・・・ メインプログラム
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

ソースファイルのダウンロード lcd1a.zip

lcd.asm

主にSC1602向けのLCD液晶表示用のライブラリである。
液晶モジュールと接続するポートはマクロで変更可能である。
busyフラグはチェックせずソフトウェアディレイで対応しているためクロック周波数が変更された場合はディレイの調整が必要
詳細は以下のリンクを参照されたい
lcd.asm

stdlib.asm

8bit,16bit割り算、2進,10進,16進数値変換等をサポートしたライブラリである

詳細は以下のリンクを参照されたい
stdlib.asm

lcd1a.asm

メインプログラムである。
IOポートの入出力の設定をし、LCDの初期化、0.5秒おきのカウント処理、2バイト整数を文字列に変換、液晶へ文字列の転送を実施している。

; LCD液晶に約0.5秒おきに0から65535までを10進数,16進数,2進数で表示する
;
; File:        lcd1a.asm
; Target:      PIC18F14K50 48Mhz
; アセンブラ:   Microchip MPASM(v5.51)
; 書き込み:     PICKit 3
; リリース:     2013/10/01 21:00
;
; 液晶表示例
;   列      0123456789abcdef
;   1行目   00255   00FF
;   2行目   0000000011111111

        #INCLUDE <p18f14k50.inc>
        #INCLUDE "lcd.inc"
        #INCLUDE "stdlib.inc"

        ; 水晶発振(12MHz) クロック分周無 PLL有効(*4)
        ; ウォッチドッグタイマ無効 低電圧プログラム書き込みモード無効
        CONFIG FOSC = HS,CPUDIV = NOCLKDIV,PLLEN=ON,WDTEN=OFF,LVP=OFF

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

        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

        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にする。

        rcall   lcd_init    ;   液晶初期化

;   液晶用バッファを空白でクリア
        lfsr    FSR0,LCD_BUF
        movlw   32
        movwf   Temp1
        movlw   ' '
buf_clr
        movwf   POSTINC0
       	decfsz  Temp1
    	goto    buf_clr

        clrf    ARGL
        clrf    ARGH

loop_deg
;   10進数文字列の作成(変換元値はARGH:ARGL)
        lfsr    FSR1,LCD_BUF
        rcall   word2deg

;   16進数文字列の作成(変換元値はARGH:ARGL)
        lfsr    FSR1,LCD_BUF+8
        rcall   word2hex
;   2進数文字列の作成(変換元値はARGH:ARGL)
        lfsr    FSR1,LCD_BUF+d'16'
        rcall   word2bin
;   バッファの内容を液晶に表示
        lfsr    FSR1,LCD_BUF
        rcall   lcd_disp
;   16bitのインクリメント
        incf    ARGL
        movlw   0
        addwfc  ARGH
;   約0.5秒の待機
        rcall   wait500
        bra     loop_deg

        goto    $           ;   自分自身で無限ループ

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

        END