;******************************************************************************
;進路予告表示機　8x8ドットマトリクスＬＥＤ制御
;PIC16F873A 
;copyright (c) 2013,14 名古屋電鉄　　http://www007.upp.so-net.ne.jp/nagoden/
;LEDDISP01.asm  2013/11/01 Ver1.00 
;******************************************************************************
;
;PIC16F873AのポートＡに入力された値によってドットマトリクスＬＥＤに文字を表示します。
;
;  USARTモードは以下の指定をしています 
;   Mode : Asyncronous transfer mode only
;   Speed: 9600 bps(32 20Mhz) 
;   Bit  : startx1 datax8 stopx1
;
; USARTモードコマンド（未確定）
;  表示　Enable/Disable
;　　　"D"+ "0"or"1"+ "@"    Hex 443040  or 443140  
;  表示パターン選択   
;　　　"P"+ "1"～"4"+ "@"    Hex 503140  or 503240 　or 503340 　or 503440　 
;　　表示文字選択　
;　　　"M"+ "1"～"6"+ "@"    Hex 4Dnn40　　ｎｎ= 31～36　 
;  
;-----------------------------------------------------------------------------
;  このソースではUSARTモードを使用したコマンド機能は組み込んでいません。
;---------------------------------------------------------------------------
; 
; RA0～RA5　　入力
; RB0～RB7	ドットマトリクスLED　カラム出力
; RC0 		LED　ROWデータ制御ビット　74HC138経由でLEDのROWを制御
; RC1 		LED　ROWデータ制御ビット　74HC138経由でLEDのROWを制御
; RC2 		LED　ROWデータ制御ビット　74HC138経由でLEDのROWを制御
; RC3		表示 Enable/Disable 74HC138を制御 highで表示		
; RC4 		モード切替用（入力）
; RC5　		モード切替用（入力）
; RC6 		TX（送信）（RESERV）
; RC7 		RX（受信）（RESERV）
;
;  RC7  RC6　（ピン開放で１）
;   0    0	ピン入力モード　表示パターン１
;   0    1 　ピン入力モード　表示パターン２
;   1    0　　ピン入力モード　表示パターン３
;   1    1 　ピン入力モード　表示パターン４
;
 
;******************************************************************************
	list      p=16f873a
	#include <p16f873a.inc>

	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF

;************************************************
;変数定義
;************************************************
;割り込みルーチンで使用
w_temp		EQU	0x20 
status_temp	EQU	0x21

PC_DATA		EQU	0x22		;ポートＣ（モード設定判定ビット用）
R_CNT		EQU	0x23		;文字の列カウント
C_CNT		EQU	0x24		;文字番号
C_PTR		EQU	0x25		;文字データのポインタ
WK_PTR		EQU	0x26		;ポインタワーク
M_OFFSET	EQU	0x27		;０、４８、９６、１４４
SW_FLG 		EQU	0x28		;スイッチフラグ
cnt1		EQU	0x29		;タイマーカウント
cnt2		EQU	0x2A		;タイマーカウント
cnt3		EQU	0x2B		;タイマーカウント
DE_MODE		EQU	0x2C		;Disable /Enable(USART制御で使用）

;マクロ定義
BANK0	MACRO
	BCF	STATUS,RP0	;BANK 0に切替
	BCF	STATUS,RP1	;
	ENDM
BANK1	MACRO
	BSF	STATUS,RP0	;BANK 1に切替
	BCF	STATUS,RP1	;
	ENDM
BANK2	MACRO
	BCF	STATUS,RP0	;BANK 2に切替
	BSF	STATUS,RP1	;
	ENDM
;*******************************************************************************
		ORG	0x000             
  		goto	INIT  				

		ORG	0x004				; 割り込みベクタ
		movwf	w_temp        	  	; ワークレジスタ退避
		movf	STATUS,w          	; ステータスレジスタをワークレジスタに
		movwf	status_temp       	; ワークレジスタ（ステータス）退避
								  	; ←ここに割り込みルーチン設定
		BANK0						; バンク０に切り替え	
		movf	status_temp,w     	;　退避ステータスのワークレジスタへ戻し
		movwf	STATUS            	; ワークレジスタからステータスへ戻し
		swapf	w_temp,f			;　ワークレジスタの戻し	
		swapf	w_temp,w          	; ワークレジスタの戻し
		retfie                    	; 割り込み終了

INIT
;*********************************************
;ＰＩＣの入力ポートと割り込みの設定
;
;*********************************************
	BANK1
	;ポートの設定
	MOVLW	06H		;コレをしないとportＡのデジタル入力ができません
	MOVWF	ADCON1		;ADCON1に06Hを設定しポートＡをすべてデジタルに
	MOVLW	B'11111111'
	MOVWF	TRISA		; ポートAはすべて入力端子
	MOVLW	B'00000000'
	MOVWF	TRISB		; ポートBは全て出力端子
	MOVLW	80H
	MOVWF	OPTION_REG	; ポートＢプルアップなし
	MOVLW	B'10110000'
	MOVWF	TRISC		; ポートCはrc0~rc3,rc6が出力端子　後は入力
	BANK0
	CLRF	PORTA		; PORTクリア
	CLRF	PORTB		; PORTクリア
	CLRF	R_CNT		; 列カウンタのクリア

	;USARTの設定 PIC12F873 20MhZ
	BANK1
	movlw	d'32'		;32→ボーレート 9600bps   9469.69=20Mhz/((32+1)*64)
	movwf	SPBRG		;SPBRGにボーレート設定		
	BANK0			;Bank 0に切り替え
	movlw	090H		;↓でシリアルピン設定、継続受信許可　に設定 
	movwf	RCSTA		;RXSTAにセット

MAIN_INIT
;*********************************************
;モードのチェック
;８ビット6文字分1ブロック　4ブロック分テーブル設定
;ポートＣの　５，６ビット目をショートピン使って切り替え
;ＵＳＡＲＴモーﾄﾞでは実行中にコマンドで切り替え可能にする
;*********************************************
	;ポートｃのRC4とRC5を読んでモードのチェック
	movf 	PORTC,w
	movwf	PC_DATA
	movlw	b'00110000'	;RC4,5のポートチェックするのでをビットマスクするため
	andwf	PC_DATA,f
	movlw	b'00110000'			
	SUBWF	PC_DATA,f	;同じパターンで引き算して０か判断
	btfss	STATUS,Z	;０かどうか判定
	goto	MODEP2
	MOVLW   d'144'		
	MOVWF	M_OFFSET	;テーブル読み込みオフセット　６（個）Ｘ８（ビット）Ｘ３（ブロック）＝１４４;
	GOTO	MAIN
MODEP2
	movf 	PORTC,w
	movwf	PC_DATA
	movlw	b'00100000'	;RC4,5のポートチェックするのでをビットマスクするため
	andwf	PC_DATA,f
	movlw	b'00100000'
	SUBWF	PC_DATA,f	;同じパターンで引き算して０か判断
	btfss	STATUS,Z	;０かどうか判定
	goto	MODEP1
	MOVLW   d'96'		
	MOVWF	M_OFFSET	;テーブル読み込みオフセット　６（個）Ｘ８（ビット）Ｘ２（ブロック）＝９６;
	GOTO	MAIN
MODEP1
	movf 	PORTC,w
	movwf	PC_DATA
	movlw	b'00010000'	;RC4,5のポートチェックするのでをビットマスクするため
	andwf	PC_DATA,f
	movlw	B'00010000'	
	SUBWF	PC_DATA,f	;同じパターンで引き算して０か判断
	btfss	STATUS,Z	;０かどうか判定
	goto	MODEP0
	MOVLW   d'48'		
	MOVWF	M_OFFSET	;テーブル読み込みオフセット　６Ｘ８＝４８
	GOTO	MAIN
MODEP0
	MOVLW   d'0'		
	MOVWF	M_OFFSET
	GOTO	MAIN
MAIN
;*********************************************
;メインルーチン
;
;*********************************************
	BSF	PORTC,3		;表示ＬＥＤEnable LS138の制御
	CLRF	C_CNT		;文字番号カウンタクリア

MAIN_LOOP
;******************************************
;入力パターンの選択　ポートA
;******************************************

	BTFSC	PORTA,0		;ポートAのビット０が０か判断
	GOTO	PIN1		;１のとき次のビットへ
	MOVF	C_CNT,W		;ビット０が０の時にすでに文字カウンタと比較
	SUBLW	d'0'
	BTFSC	STATUS,Z	;引き算して０なら変わっていないので次のビットへ
	GOTO	PIN1	
	MOVLW   d'0'		;文字カウンタを０にセットして	
	MOVWF	C_CNT
	CLRF	R_CNT		;列カウンタクリア
PIN1
	BTFSC	PORTA,1		;ポートAのビット１が０か判断
	GOTO	PIN2		;１のとき次のビットへ
	MOVF	C_CNT,W		;ビット１が０の時にすでに文字カウンタと比較
	SUBLW	d'1'
	BTFSC	STATUS,Z	;引き算して０なら変わっていないので次のビットへ
	GOTO	PIN2	
	MOVLW   d'1'		;文字カウンタを１にセットして
	MOVWF	C_CNT 
	CLRF	R_CNT		;列カウンタクリア

PIN2
	BTFSC	PORTA,2		;ポートAのビット2が０か判断
	GOTO	PIN3		;１のとき次のビットへ
	MOVF	C_CNT,W		;ビット2が０の時にすでに文字カウンタと比較
	SUBLW	d'2'
	BTFSC	STATUS,Z	;引き算して０なら変わっていないので次のビットへ
	GOTO	PIN3	
	MOVLW   d'2'		;文字カウンタを2にセットして
	MOVWF	C_CNT 
	CLRF	R_CNT		;列カウンタクリア

PIN3
	BTFSC	PORTA,3		;ポートAのビット3が０か判断
	GOTO	PIN4		;１のとき次のビットへ
	MOVF	C_CNT,W		;ビット3が０の時にすでに文字カウンタと比較
	SUBLW	d'3'
	BTFSC	STATUS,Z	;引き算して０なら変わっていないので次のビットへ
	GOTO	PIN4	
	MOVLW   d'3'		;文字カウンタを3にセットして
	MOVWF	C_CNT 
	CLRF	R_CNT		;列カウンタクリア

PIN4
	BTFSC	PORTA,4		;ポートAのビット4が０か判断
	GOTO	PIN5		;１のとき次のビットへ
	MOVF	C_CNT,W		;ビット4が０の時にすでに文字カウンタと比較
	SUBLW	d'4'
	BTFSC	STATUS,Z	;引き算して０なら変わっていないので次のビットへ
	GOTO	PIN5	
	MOVLW   d'4'		;文字カウンタを4にセットして
	MOVWF	C_CNT 
	CLRF	R_CNT		;列カウンタクリア

PIN5
	BTFSC	PORTA,5		;ポートAのビット5が０か判断
	GOTO	PIN6		;１のとき次のビットへ
	MOVF	C_CNT,W		;ビット5が０の時にすでに文字カウンタと比較
	SUBLW	d'5'
	BTFSC	STATUS,Z	;引き算して０なら変わっていないので次のビットへ
	GOTO	PIN6	
	MOVLW   d'5'		;文字カウンタを5にセットして
	MOVWF	C_CNT 
	CLRF	R_CNT		;列カウンタクリア
PIN6
	CALL	LEDDSP		;ＬＥＤ表示処理
	goto	MAIN_LOOP

;**********************************
; ＬＥＤ表示処理
;**********************************
LEDDSP
	;
	; 次の行データを出力する前に文字データ出力portをLOW（消灯になる）
	CLRF	PORTB
	; 列の信号制御　74HC138の入力A,B,Cに出力して8列の順次表示
  	MOVLW	d'0'
	SUBWF	R_CNT,w		; 列カウンタが0か確認
	BTFSC	STATUS,Z	;
	GOTO	POUT0
  	MOVLW	d'1'
	SUBWF	R_CNT,w		; 列カウンタが1か確認
	BTFSC	STATUS,Z	;
	GOTO	POUT1
  	MOVLW	d'2'
	SUBWF	R_CNT,w		; 列カウンタが2か確認
	BTFSC	STATUS,Z	; 
	GOTO	POUT2
  	MOVLW	d'3'
	SUBWF	R_CNT,w		; 列カウンタが3か確認
	BTFSC	STATUS,Z	; 
	GOTO	POUT3
  	MOVLW	d'4'
	SUBWF	R_CNT,w		; 列カウンタが4か確認
	BTFSC	STATUS,Z	; 
	GOTO	POUT4
  	MOVLW	d'5'
	SUBWF	R_CNT,w		; 列カウンタが5か確認
	BTFSC	STATUS,Z	; 
	GOTO	POUT5
  	MOVLW	d'6'
	SUBWF	R_CNT,w		; 列カウンタが6か確認
	BTFSC	STATUS,Z	; 
	GOTO	POUT6
  	MOVLW	d'7'
	SUBWF	R_CNT,w		; 列カウンタが7か確認
	BTFSC	STATUS,Z	; 
	GOTO	POUT7
;	74HC138への出力
POUT7
	BCF		PORTC,0
	BCF		PORTC,1
	BCF		PORTC,2
	GOTO	CNTINC
POUT6
	BSF		PORTC,0
	BCF		PORTC,1
	BCF		PORTC,2
	GOTO	CNTINC
POUT5
	BCF		PORTC,0
	BSF		PORTC,1
	BCF		PORTC,2
	GOTO	CNTINC
POUT4
	BSF		PORTC,0
	BSF		PORTC,1
	BCF		PORTC,2
	GOTO	CNTINC
POUT3
	BCF		PORTC,0
	BCF		PORTC,1
	BSF		PORTC,2
	GOTO	CNTINC
POUT2
	BSF		PORTC,0
	BCF		PORTC,1
	BSF		PORTC,2
	GOTO	CNTINC
POUT1
	BCF		PORTC,0
	BSF		PORTC,1
	BSF		PORTC,2
	GOTO	CNTINC
POUT0
	BSF		PORTC,0
	BSF		PORTC,1
	BSF		PORTC,2
	GOTO	CNTINC
CNTINC
	;表示バッファの内容を１行分取得
	CALL	SETCHR		;　テーブル参照ルーチン
	MOVWF	PORTB		; テーブルから取得したパターンをポートＢに出力
	;カウンタインクリメント
	INCF	R_CNT,F		;　文字列カウンタを＋１
	MOVLW	d'8'
	SUBWF	R_CNT,w		; カウンタが8か確認
	BTFSC	STATUS,Z	; ８（８を引いて０か？）
	CLRF	R_CNT		; ０の時、文字列カウンタを０
	RETURN
;**********************************
;USART受信処理
;**********************************
;未実装

;**********************************
;時間遅延ルーチン クロック20MHz用
;**********************************
;---------------------------------
; 60マイクロ秒遅延
; 1/16600bps　=　60.24μｓ　=60μｓ
;---------------------------------

dly_60u	; 60uS
	movlw	d'60'
	movwf	cnt1
dly_60u1
	nop
	nop
	nop
	nop
	decfsz	cnt1,f
	goto	dly_60u1
	return

;---------------------------------
; 100マイクロ秒遅延
;---------------------------------
dly_100u	; 100uS
	movlw	d'100'
	movwf	cnt2
dly_100u1
	nop
	nop
	nop
	nop
	decfsz	cnt2,f
	goto	dly_100u1
	return
;---------------------------------
; 600マイクロ秒遅延
;---------------------------------
dly_600u	; 600uS
	movlw	d'6'
	movwf	cnt1
dly_600u1
	call 	dly_100u
	decfsz	cnt1,f
	goto	dly_600u1
	return
;---------------------------------
; nミリ秒遅延
;call 前にワークにループ数をセット
;例：movlw		d'10'
;---------------------------------
dly_Nm	; NmS
	movwf	cnt1
dly_Nm1
	call	dly_1m
	decfsz	cnt1,f
	goto	dly_Nm1
	return

;---------------------------------
; 1ミリ秒遅延
;---------------------------------
dly_1m	; 1ms
	movlw		d'4'
	movwf		cnt2
dly_1m1
	movlw		d'250'
	movwf		cnt3
dly_1m2	; 250us
	nop
	nop
	nop
	nop
	decfsz		cnt3,f
	goto		dly_1m2
	decfsz		cnt2,f
	goto		dly_1m1
	return

;**********************************
;表示データの取り出し
;**********************************
;R_CNT　　文字の列カウント
;C_CNT	文字番号
;C_PTR　　文字データのポインタ
;WK_PTR	ポインタワーク
;M_OFFSET　０、４８、９６、１４４
SETCHR
 	;数字の1列分のデータを取り出し
	MOVF	R_CNT,F		; 文字の列カウントが0（一番左）か判断
	BTFSS	STATUS,Z	; 最初の列のときに飛び先をを計算（8倍）
	GOTO	SETCHR1
	BCF	STATUS,C	;キャリークリア
	CLRF WK_PTR
	MOVF C_CNT,w
	MOVWF WK_PTR 
	RLF	WK_PTR,F		; 2倍
	RLF	WK_PTR,F		; 4倍
	RLF	WK_PTR,F		; 8倍
SETCHR1
;8倍した値にモードによるオフセット値を加算
	MOVLW	H'01'
	MOVWF	PCLATH
	MOVF	WK_PTR,w	;8倍の値をワークに
	ADDWF	R_CNT,W		;列カウントを加算
	ADDWF	M_OFFSET,W	;オフセット値を加算
	ADDWF	PCL,F
	; １－１（１）
	RETLW	B'01111110'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011010'
	RETLW	B'00011100'
	RETLW	B'00011000'
	; １－２（２）
	RETLW	B'01111110'
	RETLW	B'00000110'
	RETLW	B'00000110'
	RETLW	B'00111100'
	RETLW	B'01100000'
	RETLW	B'01100000'
	RETLW	B'01100010'
	RETLW	B'00111100'
	; １－３（３）
	RETLW	B'00111100'
	RETLW	B'01100010'
	RETLW	B'01100000'
	RETLW	B'01100000'
	RETLW	B'00111000'
	RETLW	B'01100000'
	RETLW	B'01100010'
	RETLW	B'00111100'
	; １－４（４）
	RETLW	B'00110000'
	RETLW	B'00110000'
	RETLW	B'01111110'
	RETLW	B'00110010'
	RETLW	B'00110010'
	RETLW	B'00110100'
	RETLW	B'00111000'
	RETLW	B'00110000'
	; １－５（５）
	RETLW	B'00111100'
	RETLW	B'01100010'
	RETLW	B'01100000'
	RETLW	B'01100000'
	RETLW	B'00111110'
	RETLW	B'00000110'
	RETLW	B'00000110'
	RETLW	B'01111110'
	; １－６（６）
	RETLW	B'00111100'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'00111110'
	RETLW	B'00000110'
	RETLW	B'01000110'
	RETLW	B'00111100'
	; ２－１（７）
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00110000'
	RETLW	B'01100000'
	RETLW	B'01100110'
	RETLW	B'01111110'
	; ２－２（８）
	RETLW	B'00111100'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'00111100'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'00111100'
	; ２－３（９）
	RETLW	B'00111100'
	RETLW	B'01100010'
	RETLW	B'01100000'
	RETLW	B'01111100'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'00111100'
	; ２－４（０）
	RETLW	B'00111100'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'01100110'
	RETLW	B'00111100'
	; ２－５（入）
	RETLW	B'01000001'
	RETLW	B'00100010'
	RETLW	B'00100100'
	RETLW	B'00011000'
	RETLW	B'00001000'
	RETLW	B'00001000'
	RETLW	B'00000100'
	RETLW	B'00000110'
	; ２－６（出）
	RETLW	B'01111111'
	RETLW	B'01001001'
	RETLW	B'01001001'
	RETLW	B'00001000'
	RETLW	B'01111111'
	RETLW	B'01001001'
	RETLW	B'01001001'
	RETLW	B'00001000'
	; ３－１（犬）
	RETLW	B'01000001'
	RETLW	B'00100010'
	RETLW	B'00010100'
	RETLW	B'00010100'
	RETLW	B'00001000'
	RETLW	B'01111111'
	RETLW	B'01001000'
	RETLW	B'00101000'
	; ３－２（名）
	RETLW	B'01111100'
	RETLW	B'01000100'
	RETLW	B'01000101'
	RETLW	B'01111110'
	RETLW	B'00001100'
	RETLW	B'00010101'
	RETLW	B'00100010'
	RETLW	B'00111100'
	; ３－３（本）
	RETLW	B'00001000'
	RETLW	B'01011101'
	RETLW	B'01001001'
	RETLW	B'00101010'
	RETLW	B'00011100'
	RETLW	B'01111111'
	RETLW	B'00001000'
	RETLW	B'00001000'
	; ３－４（常）
	RETLW	B'00101010'
	RETLW	B'00101010'
	RETLW	B'00111110'
	RETLW	B'00001000'
	RETLW	B'00011100'
	RETLW	B'01010101'
	RETLW	B'01111111'
	RETLW	B'00101010'
	; ３－５（上）
	RETLW	B'01111111'
	RETLW	B'00001000'
	RETLW	B'00001000'
	RETLW	B'00001000'
	RETLW	B'00001000'
	RETLW	B'00111000'
	RETLW	B'00001000'
	RETLW	B'00001000'
	; ３－６（下）
	RETLW	B'00001000'
	RETLW	B'00001000'
	RETLW	B'00001000'
	RETLW	B'00001000'
	RETLW	B'00101000'
	RETLW	B'00011000'
	RETLW	B'00001000'
	RETLW	B'01111111'
	; ４－１（↓）
	RETLW	B'00011000'
	RETLW	B'00111100'
	RETLW	B'01111110'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011000'
	; ４－２（↑）
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'01111110'
	RETLW	B'00111100'
	RETLW	B'00011000'
	; ４－３（←）
	RETLW	B'00000000'
	RETLW	B'00000100'
	RETLW	B'00000110'
	RETLW	B'11111111'
	RETLW	B'11111111'
	RETLW	B'00000110'
	RETLW	B'00000100'
	RETLW	B'00000000'
	; ４－４（→）
	RETLW	B'00000000'
	RETLW	B'00100000'
	RETLW	B'01100000'
	RETLW	B'11111111'
	RETLW	B'11111111'
	RETLW	B'01100000'
	RETLW	B'00100000'
	RETLW	B'00000000'
	; ４－５（まる）
	RETLW	B'00111100'
	RETLW	B'01000010'
	RETLW	B'10000001'
	RETLW	B'10000001'
	RETLW	B'10000001'
	RETLW	B'10000001'
	RETLW	B'01000010'
	RETLW	B'00111100'
	; ４－６（ばつ）
	RETLW	B'10000001'
	RETLW	B'01000010'
	RETLW	B'00100100'
	RETLW	B'00011000'
	RETLW	B'00011000'
	RETLW	B'00100100'
	RETLW	B'01000010'
	RETLW	B'10000001'

	END