kuroの覚え書き

96の個人的覚え書き

ダイナミック点灯方式のプログラム例



;**************************************************************
;これは標準的な7セグメントLEDのダイナミック点灯制御例です。
;5桁のLEDに16進数の数字が、1秒周期で更新表示されます。
;表示更新時に数字が+1されます。また桁毎にも数字が+1されます。
;***************************************************************
LIST P=PIC16F84 ;CPUチップの種類を指定します
INCLUDE "P16F84.INC" ;各種の定数ラベルの標準ファイル
;を結合しておきます。
;****************************
;プログラム中で使う変数の定義
;****************************
CNT1 EQU 0DH ;タイマー用のカウンタ
CNT2 EQU 0EH ;〃
CNT3 EQU 0FH ;1秒間の繰り返し用のカウンタ
COLUM EQU 10H ;Display Digit Position
NUMBER EQU 11H ;Test Display Data
TEMP EQU 12H ;Work
;****************************
;割り込みのベクトル(未使用)
;****************************
ORG 0
GOTO MAIN ;RESET時のスタート
ORG 4
GOTO INT_ ;割り込み飛び先(未使用)
ORG 8H ;プログラム開始番地指定

;********************************
;メインプログラム
;********************************
MAIN
BCF INTCON,GIE ;割り込みすべて禁止
CLRF NUMBER ;表示データ0セット
;入出力ポート初期化
BSF STATUS,RP0 ;ページ1を指定
CLRF TRISA ;ポートA全て出力
CLRF TRISB ;ポートB全て出力
BCF STATUS,RP0 ;ページ0に戻す
MAINLP
MOVLW 28H ;繰り返し回数セット(1秒)
MOVWF CNT3 ;カウンタへ
LOOP ;桁繰り返しループ
MOVLW 10H ;最初の桁を指定
MOVWF COLUM ;保存
MOVF NUMBER,W ;表示する数字データ取り出し
MOVWF TEMP ;一時保管
NEXT ;各桁表示
MOVF TEMP,W ;表示データ取り出し
CALL DISP ;セグメント表示出力、5msec待ち
INCF TEMP,F ;表示データ+1
BCF STATUS,C ;シフト時に1が入らないように
RRF COLUM,F ;桁ビットシフト
MOVF COLUM,W ;桁データ取り出し
ANDLW 1FH ;5桁完了チェック
BTFSS STATUS,Z ;完了したか?
GOTO NEXT ;まだのとき次の桁へ
DECFSZ CNT3,F ;繰り返し完了か?
GOTO LOOP ;まだの時同じ表示繰り返し
INCF
NUMBER,F ;表示データ+1
GOTO MAINLP ;最初から繰り返し

;********************************
;表示制御サブルーチン
;5msec待ち
;********************************
DISP
CALL GET_7SEG ;数字データをセグメントデータに変換
MOVWF PORTB ;ポートBへセグメントデータ出力
MOVF COLUM,W ;桁データ取り出し
MOVWF PORTA ;ポートAへ桁データ出力
CALL TIME5M ;5msec待ちタイマー
CLRF PORTB ;次の桁に移る時のちらつき防止
RETURN

;*************************************************
;16進数をセグメントデータに変換する
;セグメントデータはPORTB1〜PORTB7用になっている
;つまり0ビット目は使わない
;*************************************************
GET_7SEG
ANDLW 0FH ;下位4ビットのみ取り出し
ADDWF PCL,F ;PCレジスタに数字を加えてジャンプ
RETLW B'01111110' ;Code 0
RETLW B'00001100' ;Code 1
RETLW B'10110110' ;Code 2 ここのデータを持って
RETLW B'10011110' ;Code 3 リターン
RETLW B'11001100' ;Code 4
RETLW B'11011010' ;Code 5
RETLW B'11111010' ;Code 6
RETLW B'00001110' ;Code 7
RETLW B'11111110' ;Code 8
RETLW B'11001110' ;Code 9
RETLW B'11101110' ;Code A
RETLW B'11111000' ;Code b
RETLW B'01110010' ;Code C
RETLW B'10111100' ;Code d
RETLW B'11110010' ;Code E
RETLW B'11100010' ;Code F

;**************************************
;Timer Routine
;TIM5M:5msec
;**************************************
TIME5M
MOVLW 9H ;About 5msec
MOVWF CNT2 ;
TIMLP2
CLRF CNT1 ;
TIMLP1
NOP ;dumy nop
NOP
DECFSZ CNT1,F
GOTO TIMLP1 ;5*256-1
DECFSZ CNT2,F
GOTO TIMLP2 ;10*((5*256-1)+3)-1
RETURN ;+3=12822*0.4usec=5.1msec
;****************************************************
;INT Interrupt Dumy Routine (ignored)
;****************************************************
INT_ RETURN
END

例2 カウントアップカウンター


LIST P=PIC16F84
INCLUDE "P16F84.INC"

;変数////////////////////////////////////////////////////////////////
NUM EQU 0X0C ;表示する数字
FIG1 EQU 0X0D ;1の位の数字
FIG10 EQU 0X0E ;10の位の数字
FIG100 EQU 0X0F ;100の位の数字
NUMTMP EQU 0X10 ;数字変換時の作業用
FIGCNT EQU 0X11
FIGLANK EQU 0X12
KEY EQU 0X13 ;入力チェック用フラグ
TIME1 EQU 0X14 ;WAIT用変数
TIME2 EQU 0X15
NUMKEY EQU 0X03 ;カウンタアップボタンのアドレス
RESETKEY EQU 0X02 ;リセットボタンのアドレス

ORG 0
GOTO MAIN
ORG 4
GOTO INTERRUPT

;メインプログラム////////////////////////////////////////////////////
MAIN CALL INIT ;初期設定
MOVLW 0X0 ;初めの数字を0にする
MOVWF NUM
CALL HEX_TO_DIG ;7セグメント表示器のパターンに変換
MAINLOOP CALL DISPFIG1 ;1の位を1ms表示
CALL WAIT1MS
CALL INPUTRESET ;リセットボタンのチェック
CALL DISPFIG10 ;10の位を1ms表示
CALL WAIT1MS
CALL INPUTNUM ;カウンタアップのチェック
GOTO MAINLOOP

;初期設定(入力・出力設定)/////////////////////////////////////////////
INIT BSF STATUS,RP0
CLRF TRISB
MOVLW 0x0C
MOVWF TRISA
BCF STATUS,RP0
RETURN

;カウンタアップボタンのチェック//////////////////////////////////////
INPUTNUM BTFSC PORTA,NUMKEY ;カウンタアップボタンをチェック
GOTO NONINPUT
BTFSC KEY,NUMKEY ;前回チェック時も入力ありなら終了
RETURN
INCF NUM,F ;カウンタアップ
CALL HEX_TO_DIG ;7セグメント表示器のパターンに変換
BSF KEY,NUMKEY ;入力ありを記録
RETURN
NONINPUT BCF KEY,NUMKEY ;入力なしを記録
RETURN

;リセットボタンのチェック////////////////////////////////////////////
INPUTRESET BTFSC PORTA,RESETKEY ;リセットボタンをチェック
GOTO NONRESET
BTFSC KEY,RESETKEY ;前回チェック時も入力ありなら終了
RETURN
CLRF NUM ;リセット
CALL HEX_TO_DIG ;7セグメント表示器のパターンに変換
RETURN
NONRESET BCF KEY,RESETKEY ;入力なしを記録
RETURN

;各桁の表示/////////////////////////////////////////////////////////
;1の位の表示
DISPFIG1 CLRF PORTB ;ポートBをいったん消去
MOVLW 0X01 ;1の位をON
MOVWF PORTA
MOVF FIG1,W ;1の位の数字を取得し、
CALL GET_7SEG ;7セグメント表示器のパターンに変換
MOVWF PORTB ;ポートBに出力
RETURN
;10の位の表示
DISPFIG10 CLRF PORTB ;ポートBをいったん消去
MOVLW 0X02 ;10の位をON
MOVWF PORTA
MOVF FIG10,W ;10の位の数字を取得し
CALL GET_7SEG ;7セグメント表示器のパターンに変換
MOVWF PORTB ;ポートBに出力
RETURN
;100の位の表示
DISPFIG100 CLRF PORTB ;ポートBをいったん消去
MOVLW 0X04 ;100の位をON
MOVWF PORTA
MOVF FIG100,W ;100の位の数字を取得し
CALL GET_7SEG ;7セグメント表示器のパターンに変換
MOVWF PORTB ;ポートBに出力
RETURN


;8bitデータを3桁の10進数に分解///////////////////////////////////////
HEX_TO_DIG MOVF NUM,W ;数字データをロード
MOVWF NUMTMP ;もとのデータを壊さないように
;NUMTMPで処理する
MOVLW D'100' ;100をロードして
MOVWF FIGLANK ;FIGLANKにセット
CALL SETFIG ;100の位を数える
MOVWF FIG100 ;FIG3に100の位の数をセット
MOVLW D'10' ;10をロードして
MOVWF FIGLANK ;FIGLANKにセット
CALL SETFIG ;10の位を数える
MOVWF FIG10 ;10の位の数をFIG2にセット
MOVF NUMTMP,W ;NUMTMPの残り(1の位)をロード
MOVWF FIG1 ;1の位をFIG1にセット
RETURN

SETFIG MOVLW D'0' ;0をロードして
MOVWF FIGCNT ;FIGCNTをリセット
FIGLOOP MOVF FIGLANK,W
SUBWF NUMTMP,F ;元のデータからFIGLANKを引く
BTFSC STATUS,C ;マイナスになるまで繰り返す
GOTO CNTPLUS
GOTO ENDFIG
CNTPLUS INCF FIGCNT,F ;プラスのときはカウンタ+1
GOTO FIGLOOP
ENDFIG MOVF FIGLANK,W ;マイナスになったら、FIGLANK
ADDWF NUMTMP,F ;を加えてプラスに戻す
MOVF FIGCNT,W
RETURN

;数字を7セグメント表示器のパターンに変換/////////////////////////////
GET_7SEG ANDLW 0X0F
ADDWF PCL,F
RETLW B'01111110' ;0
RETLW B'00011000' ;1
RETLW B'10110110' ;2
RETLW B'10111100' ;3
RETLW B'11011000' ;4
RETLW B'11101100' ;5
RETLW B'11101110' ;6
RETLW B'00111000' ;7
RETLW B'11111110' ;8
RETLW B'11111000' ;9
RETLW B'11111010' ;A
RETLW B'11001110' ;b
RETLW B'01100110' ;C
RETLW B'10011110' ;d
RETLW B'11100110' ;E
RETLW B'11100010' ;F

;1ms待機/////////////////////////////////////////////////////////////
WAIT1MS MOVLW 0X0A
MOVWF TIME2
WLOOP2 CALL WAIT01MS
DECFSZ TIME2,F
GOTO WLOOP2
RETURN

WAIT01MS MOVLW 0X52
MOVWF TIME1
WLOOP1 DECFSZ TIME1,F
GOTO WLOOP1
RETURN

;割り込み処理////////////////////////////////////////////////////////
INTERRUPT NOP
END