プロが教える店舗&オフィスのセキュリティ対策術

以前PIC16F84Aで問題なく動作しているプログラムを
初期設定を変えて(これでいいのか?も疑問)16F628Aで動かそうとしていますが
サブルーチンに入り「タイマー」のルーチンから抜け出せないみたいです。

BILD ALL ではエラーは出ません。

割込みは正常に動作します。
どこがいけないのでしょうか?

よろしくお願いいたします。

プログラムはこちらです。


;-------------------------------------------------------------------------
;     初期設定

list P=pic16f628a
include "p16f628a.inc"

__CONFIG _HS_OSC & _CP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _LVP_OFF & _MCLRE_OFF


ORG 0


GOTO MAIN

;-----------------------------------------------------------------------
; 割り込み処理

ORG 4     ;割り込みアドレス
CLRW
CLRF PORTB     ;ポートBクリア
GOTO MAIN

;-----------------------------------------------------------------------
; メインプログラム

MAIN   BCF STATUS,RP0
         MOVLW B'00000111'
        MOVWF CMCON
        BSF INTCON,INTE     ;割りこみ許可?


         BSF STATUS,RP0     ;ポートAを全て入力に設定
        MOVWF TRISA
         MOVLW H'01'     ;ポートBは0(ゼロ)以外は出力に設定
        MOVWF TRISB

        MOVLW 90H     ;INT割り込み許可
        MOVWF INTCON

        BCF STATUS,RP0     ;ポートBをクリア
        CLRF PORTB

         CLRW
;----------------------------------------------------------------------
; スイッチ入力チエック
LOOP    BTFSS PORTA,0     ;オープンSWがONか?
         GOTO OPEN      ;ONだったら OPENへ
        GOTO LOOP
;-----------------------------------------------------------------------
; オープン動作

OPEN    MOVLW 010H      ;ポートB4番に5V出力(リレーON)
         MOVWF PORTB
       MOVLW D'250'      ;動作時間 '250'設定
        MOVWF 0EH      ;アドレス0EHに250を入力
         CALL LOOP3      ;サブルーチンLOOP3を呼び出す

       GOTO MAIN      ;サブルーチンが終わったら MAIN に戻れ

;------------------------------------------------------------------------

;-----------------------------------------------------------------------

; サブルーチン(タイマー)

TIMER1    MOVLW D'220'
          MOVWF 0CH

LOOP1    NOP
          DECFSZ 0CH,1
          GOTO LOOP1
        RETURN

TIMER2     MOVLW D'100'      ;アドレス0DHに100を入力
         MOVWF 0DH

LOOP2    NOP
          CALL TIMER1      ;TIMER1を呼び出し(行く)
          DECFSZ 0DH,1      ;アドレス0DH から1を引き算する
          GOTO LOOP2      ;結果が"0"でなかったら LOOP2に戻ってまた引き算
         RETURN       ;引き算の結果が"0"になったら「CALL」した「次に(下)」へ戻る

LOOP3    NOP      ;何もしない
         CALL TIMER2      ;TIMER2を呼び出す(行く)
        DECFSZ 0EH,1
        GOTO LOOP3
         RETURN


END    END

A 回答 (2件)

SFRの中でEEPROM関係のレジスタのバンクが違いますが、


EEPROMは使っていますか?

シュミレーションはやってみましたでしょうか。
16f628を使い始めた頃、これで随分と助けられたものですから、
あまり、一言にはならなかったみたいですね。

この回答への補足

汎用RAMの先頭アドレスが違っていたのを直さないの原因でした。
有難うございました。

補足日時:2012/11/11 11:30
    • good
    • 0
この回答へのお礼

早々のお答え有難うございます。

EEPROMは使用しておりません。

シュミレーションは「あっち・こっち」LED出力してチエックしましたが
その結果「ループ」の中から抜け出せないようなのが分かりました。

16F84Aでは問題なくループから抜けて、次の入力待ちになります。
不思議で仕方ありません。

お答え有難うございました。

お礼日時:2012/11/06 16:19

ソースの「丸投げ」はいけませんね!



少なくとも、「シミュレータ」があるわけですから、「何のためのシミュレータ?」ってことになります。

>LOOP1    NOP
          DECFSZ 0CH,1
          GOTO LOOP1


このような組み方はあまり望ましくありません。ループは必ずぬけられるようにしておかなければ、あなたのように悩まされることになります。

この内容で「シミュレータ」をつかってつきとめることができないのならば、どのようなプログラムもデバッギングできません。

仮にループが100回だろうと1000回だろうとわからなければ1つづつステップして調べていけば必ず原因がわかります。

ソフトウェアでカウンタがゼロになるチェックが甘すぎるのと、ソフトウエェアでダミーループに頼りすぎているプログラミンであるにもかかわらず「割込み」を使用しているので余計に混乱しているのではないでしょうか?

16F84Aで正常に動いたから・・・でほとんどプログラミング内容の検証はしてない・・・ということが大元の原因であることは想像つきますんで。


いい機会ですので、1つづつステップ実行でよく動作を確認されてください。「他人にデバッグさせる」」ようなマネはしないように!
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!