kuroの覚え書き

96の個人的覚え書き

16F84Aでシフトインジケーター



12f675のプログラムが上手く動かなかったので、とりあえず16F84A用に書き直してみたところ上手く動作することがわかった。まあとりあえずはそれでいいんだけれど12F675も使いこなせるようになりたいのでもうちょっと調べないと。と思っていたら12F675でもちゃんと動作するようになった。よしよし。

ちなみに作成したプログラムは以下の通り


LIST P=PIC16F84
INCLUDE "P16F84.INC"
__CONFIG _WDT_OFF & _PWRTE_ON & _HS_OSC
;****************************************************
; 変数定義とレジスタ割付
;****************************************************
CBLOCK 0CH ;先頭の番地を指定 16F84Aなら0CH 16F819なら020H
BYTE0 ;周波数カウンタ0
BYTE1 ;周波数カウンタ1
BYTE2 ;周波数カウンタ2
LPCNT1 ;LOOP COUNTER
LPCNT2 ;LOOP COUNTER
OVRFLW ;OVER FLOW FLAG
TEMP ;TEMPOLARY WORK
CNT1
CNT2
CNT3
CNT4
ENDC ;定義終わり

;********************************
; JUMPING VECTOR
;********************************
ORG 0
GOTO MAIN

ORG 4
GOTO INTPROC
INTPROC RETURN

ORG 08H

;********************************
; MAIN ROUTINE
;********************************

MAIN
BCF INTCON,GIE ;INTERRUPT DISABLE
BTFSC INTCON,GIE
GOTO $-2 ;RETRY BCF INTCON,GIE

CALL PORT_INI ;PORT A,B INITIALIZE

MAINLP
CALL MEASURE ;TMR0カウント
CALL LED ;LED点灯
GOTO MAINLP ;表示更新

;********************************
;計測実行サブルーチン
;VMAXのタコメーターパルスにあわせるとゲートタイムは0.6秒
;だが0.3秒をゲートタイムに使用。
;PORTAのRA4がゲート制御ピン
;10MHZオシレータ使用が前提
;********************************
MEASURE
BSF STATUS,RP0 ;SET PAGE 1
MOVLW 068H ;SET TO NO PRESCALE
MOVWF OPTION_REG ;
BCF STATUS,RP0 ;SET PAGE 0
CLRF TMR0 ;カウンタリセット
BCF PORTA,4 ;ゲートを閉める

;**** ゲートタイム300msec *****
BSF PORTA,4 ;ゲートを開ける
CLRF OVRFLW ;OverFlowフラグをクリア
CALL MESLOOP ;249998STEP
CALL MESLOOP ;249998STEP
CALL MESLOOP ;249998STEP
NOP
NOP
NOP
NOP
BCF PORTA,4 ;ゲートを閉める (250000*3)
RETURN

;**** 計測実行ループ(249,996STEPS) ****
MESLOOP MOVLW 08DH ;ループ繰り返しカウンタ=141
MOVWF LPCNT1
;++++++++++
MESLP1 MOVLW 088H ;第二カウンタ=136
MOVWF LPCNT2 ;
;***********
MESLP2 BTFSS INTCON,T0IF ;13 STEPS LOOP
GOTO DUMY1
BCF INTCON,T0IF ;T0IFフラグをリセット
MOVLW 1 ;カウント更新用定数
GOTO NEXT
DUMY1 NOP ;時間調整用NOP
NOP
MOVLW 0 ;カウンタ更新用定数
NEXT ADDWF BYTE1,F ;BYTE1+T0IF
RLF BYTE1,W ;CARRY TO D<0>
ANDLW 1 ;キャリーだけ取り出し
ADDWF BYTE2,F ;BYTE2+CARRY
DECFSZ LPCNT2,F ;ループ終了か?
GOTO MESLP2 ;
;**********
NOP
MESLP3 DECFSZ LPCNT1,F ;(13*LPCNT2+5)*LPCNT1
GOTO MESLP1 ;(13*136+5)*141=249993-1
;+++++++++++++++
RETURN ;+2+2=249996

;************************
;LED駆動ルーチン
;************************
LED MOVF TMR0,W ;カウント値を読み込み
MOVWF TEMP ;
RPM1K MOVLW 06H ;1200rpm以上か
SUBWF TEMP,F ;元のデータから引く
BTFSC STATUS,C
GOTO RPM3K ;プラスの時3000rpm判定へ
FLASH MOVLW 01H
MOVWF PORTB
CALL TIME50M
CALL TIME50M
CALL TIME50M
CALL TIME50M
CALL TIME50M
MOVLW 0H
MOVWF PORTB
CALL TIME1S
RETURN

RPM3K MOVLW 09H ;3000rpm以上か
SUBWF TEMP,F ;元のデータから引く
BTFSC STATUS,C
GOTO RPM6K ;プラスの時6000rpm判定へ
NOSIG MOVLW 0H
MOVWF PORTB
RETURN
RPM6K MOVLW 0FH ;6000rpm以上か
SUBWF TEMP,F ;元のデータから引く
BTFSC STATUS,C
GOTO RPM9K ;プラスの時9000rpm判定へ
SIG1ST MOVLW 01H ;00000001
MOVWF PORTB ;RB0点灯
RETURN
RPM9K MOVLW 0FH ;3000rpm以上か
SUBWF TEMP,F ;元のデータから引く
BTFSC STATUS,C
GOTO SIG3RD ;プラスの時
SIG2ND MOVLW 03H ;00000011
MOVWF PORTB ;RB0点灯
RETURN
SIG3RD MOVLW 07H ;00000111
MOVWF PORTB ;RB0点灯
RETURN
;************************************
; PORT A & B INITIALIZE ROUTINE
;************************************

PORT_INI
BSF STATUS,RP0 ;SET PAGE 1
MOVLW 0H ;PORTB OUTPUT SET
MOVWF TRISB
MOVLW 018H ;00011000 ONLY RA3,4 INPUT
MOVWF TRISA ;PORTA SET
MOVLW 057H ;1010111 OPTION SET TMR0=1:256
MOVWF OPTION_REG ;FOR TMR0
BCF STATUS,RP0 ;SET PAGE 0
CLRF PORTB ;ALL CLEAR
RETURN

;
;タイマーサブルーチン10MHzオシレータの場合
;10MHzの場合周期は0.1usec、実行サイクルは0.4usec
;
;0.2msecサブルーチン 500サイクル*0.4usec
TIME02M MOVLW 07CH ;1 124回まわす
MOVWF CNT1 ;1 2
TIMLP1 NOP ;1
DECFSZ CNT1,F ;1
GOTO TIMLP1 ;2 2+4*124-1=497
NOP ;1 498
RETURN ;2 500 500*0.4usec=0.2msec
;5msec 12500サイクル
TIME5M MOVLW 019H ;1 25回まわす
MOVWF CNT2 ;1
TIMLP2 CALL TIME02M ;2+500=502
DECFSZ CNT2,F ;1
GOTO TIMLP2 ;2 2+505*25-1=12626
RETURN ;2 12628 5.05msec
;50msec 125000
TIME50M MOVLW 0F8H ;248回
MOVWF CNT3 ;ここまでで2サイクル
TIMLP3 CALL TIME02M ;2+500
DECFSZ CNT3,F ;1
GOTO TIMLP3 ;2 2+505*248-1=125241
RETURN ;2 125243 50.1msec
;1sec
TIME1S MOVLW 014H ;20回
MOVWF CNT4 ;50msec * 20
TIMLP4 CALL TIME50M
DECFSZ CNT4,F ;このループは50msec
GOTO TIMLP4
RETURN

END