;+---------------------------------------+
;| 7セグであそぼー |
;+---------------------------------------+
;| PORATA |
;| 0,1...桁コントロール |
;| 00... 左 |
;| 01... 真ん中 |
;| 10... 右 |
;| 11... 点灯しない |
;| 2...未使用 |
;| 3...ボタンのLED |
;| (HIで点灯) |
;| 4...唯一の入力 |
;| 押しボタンスイッチ |
;| 押されるとLow |
;| PORTB |
;| 0...未使用 |
;| 1〜7...LEDにつながってる |
;| Lowレベルで点灯 |
;+---------------------------------------+
LIST P=PIC16F84A
INCLUDE "P16F84A.INC"
__CONFIG 0x3FFA
;
CBLOCK 0x0E ;各ファイルレジスタを0x0E番地から配置
;
COUNT1
COUNT2
COUNT3
CNT
BUF
LEFT
CENT
RIGH
E_ADRS
E_DATA
CNT2
;
ENDC
;
ORG 0x2100 ;EEPROM初期化
DE 0,0,0,0
;
ORG 0
GOTO BOOT
;
BOOT BSF STATUS,RP0 ;ポート設定
CLRF TRISB ;ポートB 全部出力
MOVLW 0x10 ;ポートA 4のみ入力
MOVWF TRISA ;
BCF STATUS,RP0 ;
;
MOVLW 0x03 ;初期出力設定
MOVWF PORTA
MOVLW 0xFF
MOVWF PORTB
;
MOVLW 0x10 ;誤動作防止
CALL TIM10m
;
CLRF CNT ;変数初期化
CLRF E_ADRS
CALL EE_READ
MOVWF LEFT
;
INCF E_ADRS,F
CALL EE_READ
MOVWF CENT
;
INCF E_ADRS,F
CALL EE_READ
MOVWF RIGH
;
;メイン部
MAIN CALL HYOUJI
BTFSC PORTA,4
GOTO MAIN
;
CALL KASAN
;
MOVLW 0x64
MOVWF BUF
MOVWF CNT
;
LOOP1 BTFSC PORTA,4 ;押されている間はカウントしない
GOTO MAIN
CALL HYOUJI
DECFSZ BUF,F ;でも、やっぱり鬱陶しいから
GOTO LOOP1 ;オートリピータ搭載
;
CALL KASAN
;
MOVLW 0x0A
SUBWF CNT,W
BTFSC STATUS,Z
MOVLW 0x0A
MOVWF CNT
MOVWF BUF
;
GOTO LOOP1
;
KASAN BSF PORTA,3
;
INCF RIGH,F ;右側の値をインクリメント
MOVLW 0x06 ;10進補正
ADDWF RIGH,W ;10+6→16
BTFSC STATUS,DC ;デジットキャリーオーバーフロー?
MOVWF RIGH
MOVLW 0x0F ;
ANDWF RIGH,W ;
BTFSC STATUS,Z ;右側が0になるようだったら
;
INCF CENT,F ;真ん中の値をインクリメント
MOVLW 0x06 ;上の二つと同じ処理
ADDWF CENT,W
BTFSC STATUS,DC
INCF LEFT,F
MOVLW 0x06 ;
ADDWF CENT,W ;
BTFSC STATUS,DC ;
MOVWF CENT
;
MOVLW 0x06
ADDWF LEFT,W
BTFSC STATUS,DC
MOVWF LEFT
;
RETURN
;
HYOUJI MOVLW 0xFF ;前回の表示がかさらないように
MOVWF PORTB ;LEDを消灯しておく
MOVLW 0x00
MOVWF PORTA ;左側のLEDを選択
MOVF LEFT,W
CALL TBL
MOVWF PORTB
MOVLW 0x20 ;ウェイトをかけて目で見えるようにする
CALL TIM50
;
MOVLW 0xFF ;前回の表示がかさらないように
MOVWF PORTB ;LEDを消灯しておく
MOVLW 0x01 ;
MOVWF PORTA ;真ん中のLEDを選択
MOVF CENT,W
CALL TBL
MOVWF PORTB
MOVLW 0x20 ;ウェイトをかけて目で見えるようにする
CALL TIM50
;
MOVLW 0xFF ;前回の表示がかさらないように
MOVWF PORTB ;LEDを消灯しておく
MOVLW 0x02 ;
MOVWF PORTA ;右のLEDを選択
MOVF RIGH,W
CALL TBL
MOVWF PORTB
MOVLW 0x20 ;ウェイトをかけて目で見えるようにする
CALL TIM50
;
;
RETURN
;
TBL ANDLW 0x0F
ADDWF PCL,F
RETLW 0x81 ;0 (0100 0001)
RETLW 0xF3 ;1 (1111 0011)
RETLW 0x49 ;2 (0100 1001)
RETLW 0x61 ;3 (0110 0001)
RETLW 0x33 ;4 (0011 0011)
RETLW 0x25 ;5 (0010 0101)
RETLW 0x05 ;6 (0000 0101)
RETLW 0xB1 ;7 (1011 0001)
RETLW 0x01 ;8 (0000 0001)
RETLW 0x21 ;9 (0010 0001)
RETLW 0x11 ;A (0001 0001)
RETLW 0x07 ;b (0000 0111)
RETLW 0x8D ;C (1000 1101)
RETLW 0x43 ;d (0100 0011)
RETLW 0x0D ;E (0000 1101)
RETLW 0x1D ;F (0001 1101)
RETURN
;
;------ 10mSタイマー ------------
;
TIM10m MOVWF COUNT1
T1 MOVLW 0xC8 ;W <- 200
CALL TIM50
DECFSZ COUNT1,F
GOTO T1
RETURN
;
;------ 50μSタイマー ----------
;
TIM50 MOVWF COUNT2
T2 MOVLW 0x20
MOVWF COUNT3
T3 DECFSZ COUNT3,F
GOTO T3
DECFSZ COUNT2,F
GOTO T2
RETURN
;
MEMORY MOVLW 0x00
MOVWF E_ADRS
MOVF LEFT,W
MOVWF E_DATA
CALL EE_WRITE
;
MOVLW 0x01
MOVWF E_ADRS
MOVF CENT,W
MOVWF E_DATA
CALL EE_WRITE
;
MOVLW 0x02
MOVWF E_ADRS
MOVF RIGH,W
MOVWF E_DATA
CALL EE_WRITE
RETURN
;
EE_READ
MOVF E_ADRS,W ;データエリアのアドレス指定
MOVWF EEADR ;アドレスをEEADRへセット
BSF STATUS,RP0 ;PAGE1へ切替え
BSF EECON1,RD ;読み出し開始
BCF STATUS,RP0 ;PAGE0に戻る
MOVF EEDATA,W ;Wレジスタにデータ取り出し
RETURN
;
EE_WRITE
BCF STATUS,RP0 ;Set to page 0
MOVF E_ADRS,W ;データエリアのアドレス指定
MOVWF EEADR ;Address set
MOVF E_DATA,W ;書き込むデータセット
MOVWF EEDATA ;Data set
BSF STATUS,RP0 ;Set to Page 1
BSF EECON1,WREN ;Set WR Enable
MOVLW 55H ;Write Sequence
MOVWF EECON2 ;Start write
MOVLW 0AAH
MOVWF EECON2
BSF EECON1,WR ;Go write
WR_LP ;書き込み確認待ちループ
BTFSC EECON1,WR ;Check Write end
GOTO WR_LP
BCF STATUS,RP0 ;Return to page 0
RETURN
;
END