概要

LCD液晶に約1秒おきに0から255までを10進数で表示する。
LCD液晶はSC1602を対象としているが、液晶モジュールの電源の接続をVDD,GNDを入れ替えればSC2004でも対応可能。ただし16文字*2行でしか表示されないので注意。
約1秒間隔は、timer0による割り込みにより設定する。timer0はアップカウント動作を開始し16bitカウンタがオーバーフローしたときに後に割り込みが発生する。timer0は初期値を自動プリセットできないので、割り込み処理ルーチンで再度、timer0を設定している。CPUクロックを分周しているまてクロック周波数に依存している。
クロックはUSB-IOで接続済みの12MHzのセラミック振動子を使用しPLLで4倍にしている。書込みはPICKit3を前提とする。
液晶表示例

HelloPIC18F14K50
 123sec
回路は次のとおりである。
回路図(PNG) 回路図(PDF) 回路図(DXF)

プログラムの説明

ソースファイル

以下のファイルで構成されている
timer0a.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

timer0a.asm

メインプログラムである。
IOポートの入出力の設定をし、LCDの初期化サブルーチンコール、timer0の設定をし待機する。約1秒後に割り込みが発生するので、再度timer0を設定し液晶表示後、復帰する。

; LCD液晶に約1秒おきに0から255までを10進数で表示する
;
; File:        timer0a.asm
; Target:      PIC18F14K50 48Mhz
; アセンブラ:   Microchip MPASM(v5.51)
; 書き込み:     PICKit 3
; リリース:     2013/10/01 21:00
;
; 液晶表示例
;   列      0123456789abcdef
;   1行目   HelloPIC18F14K50
;   2行目   000 sec
;
; タイマー0を使用して1秒置きに割り込みをかけてカウントする。
;


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

        #INCLUDE "lcd.inc"
        #INCLUDE "stdlib.inc"

;   プログラムメモリadsのアドレスをTLPTRレジスタに上書きする

LDTBLPTR MACRO   ads
        movlw   UPPER ads
        movwf   TBLPTRU
        movlw   HIGH ads
        movwf   TBLPTRH
        movlw   LOW ads
        movwf   TBLPTRL
        ENDM

        UDATA   ; 変数の定義
Tcount1     RES 1      ; wait
Tcount2     RES 1      ; wait
Tcount3     RES 1      ; wait
LCD_WRITE   RES 1      ; writeデータを指定
LCD_TEMP    RES 1
LCD_BUF     RES d'32'     ; 16*2文字分のバッファ
Temp1       RES 1      ; サブルーチン用の変数
ARG1        RES 1      ; サブルーチン引数
BYTE2HEX_TEMP RES 1
COUNT       RES 1
ARGL        RES 1
ARGH        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

            GLOBAL  LCD_WRITE,LCD_TEMP,Temp1
            GLOBAL  Tcount1,Tcount2,Tcount3
            GLOBAL  DIV_A,DIV_MOD,DIV_B,DIV_MODL,DIV_MODH,DIV_AL,DIV_AH,ARGH,ARGL,ARG1
            GLOBAL  BYTE2HEX_TEMP

;   Timer0 1秒設定値
TMR0L_1SEC EQU d'229'
TMR0H_1SEC EQU d'72'       ;  65536-46875=72*256+229

LED_ADS     EQU PORTC
LED0        EQU 0

        CODE
        ORG 0
        goto   start    ;   リセット時
        org 08h
        goto   inth     ;   割り込み

start
        clrf    ANSEL   ; RC3-RC0,RA4をデジタル入力バッファに設定
        clrf    ANSELH  ; RB5-RB4,RC7-RC6をデジタル入力バッファに設定
        clrf    SLRCON  ; PORTA,PORTB,PORTCをスルーレートを標準に設定
        clrf    TRISA   ; PORTAを全部出力に設定
        movlw   b'11110000'
        movwf   TRISB   ; RB7-RB4を入力に設定
        movlw   b'00000010' ; RC1を予約
        movwf   TRISC   ; PORTCの入出力を設定。
        clrf    PORTC   ; PORTCをクリア
;       Timer0設定
        movlw   b'10000111' ; 16bit FOSC/4/256=46875Hz
        movwf   T0CON
        movlw   TMR0H_1SEC
        movwf   TMR0H
        movlw   TMR0L_1SEC
        movwf   TMR0L

        call    lcd_init    ;   液晶初期化

        movlw   d'32'
        movwf   Temp1

        LDTBLPTR lcd_init_str
        lfsr    FSR0,LCD_BUF
lcd_init_str_set_loop
        tblrd   *+          ;   プログラムメモリTBLPTRから読み出し後TBLPTRを+1する
        movf    TABLAT,W
        movwf   POSTINC0    ;   間接アドレッシング アドレスはアクセス後に+1される
        decfsz  Temp1       ;   Temp1から1を引き結果が0になるまで繰り返す
        bra     lcd_init_str_set_loop

        lfsr    FSR1,LCD_BUF
        call    lcd_disp

        clrf    RCON
        movlw   b'00000100' ; timer0高位割り込み RBプルアップ
        movwf   INTCON2
        movlw   b'10100000' ; timer0オーバーフロー割り込み有効
        movwf   INTCON
        bsf      LED_ADS,LED0
        clrf    COUNT
        goto    $

inth    ;   高位割り込み
        bcf     INTCON,TMR0IF ;   割り込みフラグクリア

        movlw   TMR0H_1SEC
        movwf   TMR0H
        movlw   TMR0L_1SEC
        movwf   TMR0L
        btg      LED_ADS,LED0

        incf    COUNT
        movf    COUNT,W
        movwf   ARG1
        lfsr    FSR1,LCD_BUF+d'16'
        call    byte2deg
        lfsr    FSR1,LCD_BUF
        rcall   lcd_disp

        retfie  FAST


lcd_init_str
;                0123456789abcdef
        DB      "HelloPIC18F14K50"
        DB      "    sec         "

        END