; led_1.asm	for PIC16F877						2017.11.01
;		for PIC12F675						2011.06.25
;               for PIC16F648A						2009.07.09
;									2005.01.05
;									2004.12.03
;									by M.Yanaka
;	1個のLEDの点滅（一定周期）
;
	LIST	P=16F877	; マイコンはPIC16F877
	INCLUDE	P16F877.INC	; インクルードファイルを指定
;*******************************
;	コンフィギュレーションビットの設定
;*******************************
	__CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BODEN_OFF &  _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_OFF & _CPD_OFF
				; 	_HS_OSC		HS高速発振
				; 	_WDT_OFF	ウォッチドッグタイマはOFF
				; 	_PWRTE_ON	パワーアップタイマはON
				; 	_CP_OFF		コードプロテクトはOFF
				; 	_MCLRE_ON 	マスタクリアはON
				; 	_BODEN_OFF	低電圧リセットはOFF
				; 	_WRT_ENABLE_ON	プログラムメモリ書き込みはON
				; 	_LVP_OFF	低電圧書き込みはOFF
				; 	_DEBUG_OFF	オンボードデバッグはOFF
				; 	_CPD_OFF	EEPRROMプロテクトはOFF
;--------------------------------
	CBLOCK	20H		; ファイルアドレス20H番地から変数を割り当てる
	CNT0, CNT1, CNT2	; 遅延用カウンタ
	ENDC			; CBLOCK終了
;--------------------------------
	ORG	0		; リセットベクタ(プログラムアドレス0番地)
	GOTO	START		; STARTへ跳ぶ
;--------------------------------
	ORG	4		; 割り込みベクタ(プログラムアドレス4番地)
	GOTO	START		; （今回は割り込みを使用しない）
;*******************************
;	メインルーチン
;*******************************
START:
	CALL	INIT_IOPORT	; I/Oポートの初期設定
LOOP:
	BSF	PORTD,0		; RD0 <- 1
	MOVLW	0x0A		; 約 0.5 秒間の遅延
	CALL	DELAY
	BCF	PORTD,0		; RD0 <- 0
	MOVLW	0x0A		; 約 0.5 秒間の遅延
	CALL	DELAY
	GOTO	LOOP		; LOOPへ跳ぶ（始めから繰り返す）	
;*******************************
;	I/Oポートの初期設定
;*******************************
INIT_IOPORT:
	BSF	STATUS,RP0	; バンク1へ切り替えて、
;	MOVLW	H'FF'		; ポートAは、
;	MOVWF	TRISA		; 	すべて入力ピンにする
	CLRF	ADCON1		; ポートAはすべてアナログ入力ピンにする
	MOVLW	H'FF'		; ポートBは、
	MOVWF	TRISB		; 	すべて入力ピンにする
	CLRF	TRISC		; ポートCはすべて出力ピンにする
	CLRF	TRISD		; ポートDはすべて出力ピンにする
	CLRF	TRISE		; ポートEはすべて出力ピンにする
	BCF	STATUS,RP0	; バンク0へ切り替える
	RETURN
;*******************************
;	ソフトウェアタイマー		おおよそ (Wの内容) x 250 x 250 x 4 x 0.2μs
;				     = (Wの内容) x 50ms だけ遅延させる
;*******************************
DELAY:
	MOVWF	CNT0		; Wの内容をCNT0へ入れる
DELAY_0:
	MOVLW	0xFA		; CNT1の内容を250にする
	MOVWF	CNT1		; 
DELAY_1:
	MOVLW	0xFA		; CNT2の内容を250にする
	MOVWF	CNT2		; 
DELAY_2:
	NOP
	DECFSZ	CNT2,F		; CNT2から1を引いて、
	GOTO	DELAY_2		; 	0以外ならDELAY_2へ跳ぶ
	DECFSZ	CNT1,F		; CNT1から1を引いて、
	GOTO	DELAY_1		; 	0以外ならDELAY_1へ跳ぶ
	DECFSZ	CNT0,F		; CNT0から1を引いて、
	GOTO	DELAY_0		; 	0以外ならDELAY_0へ跳ぶ
	RETURN
;--------------------------------
	END			; プログラムの終わり
