PIC18F4685 のプログラミング
カナダに住む日本人です。
昨日、日本語が使える家のパソコンからOKWAVEに質問をしようとしましたが、どうしてもカテゴリーを選択できず、送ることができなかったため、作成した質問をUSBスティックにコピーして、英語しか使えない会社のパソコンからその質問を投稿しました。
日本語のコードを解読できないパソコンだったために、文字化けを起こしましたが、日本語のできるパソコンで開けばちゃんと読めるのではないかと思ったからです。しかし家に帰ってきて自分の質問を開いてみると文字化けしたままでした。したがって、誰にも質問内容が読めないことがわかりましたので、もう一度家のパソコンから送ってみたいと思います。
質問:
PIC18F4685を使って、スイッチを押した回数を表示するバイナリーカウンターを作ろうとしています。
以下のようなプログラムを書いて、PICkit2 でデバイスに書き込み、添付の写真のように配線しましたが、意図どおりに動いてくれません。環境はMPLAB IDE を使っていて、MPLAB SIMをデバッガーとして使い、シミュレーションもしてみました。RA4ピンに擬似入力(set high) を入れると、ちゃんとカウントアップしていて、PORT C への出力もカウンターどうりになっています。ですから、プログラムは間違ってはいないと思います。
ところが、電源を入れると4つのLEDがすべて点灯し、スイッチを押しても何の変化もありません。
ハードの仕様は次のようにしています。
バーLED用の直列抵抗:1kオーム
スイッチ用プルアップ抵抗:10kオーム
スイッチ端子:normally contact で、押せば+5VがRA4に送られているのを確認済み
電源:何かの家電品のアダプターで、5V、300mA
Vdd と Vss:32、31ピンのみ接続、11,12ピンに平行接続しても何も変わらない
発信器:20MHzクリスタルがOSC1,OSC2の間に接続されている、15pFのコンデンサも使用
下にあるプログラムは、コメント部分などは極力省略してあります。
何が問題なのか、いろいろ考えましたがわかりません。
どなたかお知恵を貸してください。お願いします。
LIST P=18F4685 ;directive to define processor
#include <P18F4685.INC> ;processor specific variable definitions
; Oscillator Selection:
CONFIG OSC = XT
UDATA
WREG_TEMP RES 1 ;variable in RAM for context saving
STATUS_TEMP RES 1 ;variable in RAM for context saving
BSR_TEMP RES 1 ;variable in RAM for context saving
UDATA_ACS
EXAMPLE RES 1 ;example of a variable in access RAM
COUNT RES 1 ;counter
DVAR RES 1 ;inner loop counter
DVAR2 RES 1 ;outer loop counter
; This code will start executing when a reset occurs.
RESET_VECTOR CODE 0x0000
goto Main ;go to start of main code
HIGH_INT_VECTOR CODE 0x0008
bra HighInt ;go to high priority interrupt routine
LOW_INT_VECTOR CODE 0x0018
bra LowInt ;go to low priority interrupt routine
CODE
HighInt:
; *** high priority interrupt code goes here ***
retfie FAST
LowInt:
movff STATUS,STATUS_TEMP ;save STATUS register
movff WREG,WREG_TEMP ;save working register
movff BSR,BSR_TEMP ;save BSR register
; *** low priority interrupt code goes here ***
movff BSR_TEMP,BSR ;restore BSR register
movff WREG_TEMP,WREG ;restore working register
movff STATUS_TEMP,STATUS ;restore STATUS register
retfie
;******************************************************************************
;Start of main program
; The main program code is placed here.
Main:
; *** main code goes here ***
START CLRF LATA ; CLEAR LATCH A
CLRF PORTA
SETF TRISA ; SET PORTA AS INPUT
CLRF LATC ; CLEAR LATCH C
CLRF PORTC
CLRF TRISC ; SET PORTC AS OUTPUT
CREST MOVLW B'00000000' ;RESET COUNTER VALUE
MOVWF COUNT ; INITIALIZE COUNTER
LOOP BTFSS PORTA,4 ; TEST BIT 4 OF PORT A & SKIP IF SET
GOTO LOOP ; ELSE LOOP BACK
CALL DEBOUNCEDELAY
CALL COUNTUP
CHKRLS BTFSC PORTA,4 ;CHECK IF THE SWITCH IS RELEASED
GOTO CHKRLS
CALL DEBOUNCEDELAY
GOTO LOOP
;******** END OF MAIN ****************************************
; *** SUBROUTINES **************
COUNTUP
INCF COUNT,F
COMF COUNT,W ; complement COUNT
MOVWF PORTC
RETURN
;*********************************
DEBOUNCEDELAY
MOVLW 0x40 ; set literal value 0x40 to W register
MOVWF DVAR2,A ; move the value from W register to variable DVAR2
; meaning set outer delay loop
DELAYOUTER
MOVLW 0xFF ; set literal value 0xFF to W register
MOVWF DVAR,A ; move the value from W register to variable DVAR
; meaning set inner delay loop
DELAYINNER
DECFSZ DVAR,F,A ; decrement DVAR and skip next if it is 0
GOTO DELAYINNER ; else, repeat until DVAR becomes 0
DECFSZ DVAR2,F,A ; decrement DVAR2 and skip next if it is 0
GOTO DELAYOUTER ; else, repeat until DVAR2 becomes 0
RETURN
;******************************************************************************
;End of program
END