• 締切済み

PIC16F193X割り込み時の退避・復帰処理方法

ICマイコンでの割り込み処理について、16F193Xの型番では割り込み発生時における退避・復帰が自動的に行われると認識しているのですが、下記型番では以前の様に wレジスタ、status,PCLATh等のレジスタを退避・復帰をプログラムで保存しておく必要がなくなったということでしょうか? 使う割り込みはタイマー割り込み(timer0)とし、割り込処理中の割り込みは禁止とした場合 因みに割り込みは以下の様に発生させ ////////////////////////// org   0 goto start org 4 goto INTLAP ////////////////////////// INTLAP BCF INTCON,2 INCF TES_CNT,1 RETFIE 割り込み処理中にTES_CONのレジスタ内容をPORTAの出力pinをオシロスコープで観察できる簡単なプログラムで走らせると動作していることが確認できましたが、退避・復帰が行われているかは不明です。 他に自動退避・復帰を確実に実行するためのプログラム等の操作を怠っていないでしょうか? 初心者で認識が誤っていないのか判断が出来ません。 対象型番 PIC16F1933 ? PIC16F1934? PIC16F1936 ? PIC16F1937? PIC16F1938 ? IC16F1939 PIC16F193X/LF193Xデータシート記述より(P71,72) 〇「このデータシートに記載されているデバイスRETFIE 命令では、割り込み前に実行していたアドレスをスタックから取得し、シャドウ レジスタから保存した内容を回復し、GIE ビットをセットすることによって、ISR から通常動作に復帰します。」 内容保存機能 〇「割り込み動作に遷移する際、復帰時の PC アドレス値がスタックに保存されます。また、次に示すレジスタ値も自動的にシャドウ レジスタに保存されます。 ・W レジスタ ・ ステータス レジスタ (TO および PD を除く) ・BSR レジスタ ・FSR レジスタ ・ PCLATH レジスタ 割り込みサービス ルーチンから通常動作に戻るとき、自動的にこれらのレジスタ値が回復されます。 とあります。

みんなの回答

回答No.1

古い^^PIC16F88時代しか知らないんですが^^ 早い話が INTベクター内で inc w してみればわかるんじゃないかな。 で、メインループで mov w,何か lp: cmp w,何か jz lp 命令忘れたので、ニモニックはそれっぽくしてください^^ 外部で変更されるなら、このループは終わるはず! どっちにしても”F"チップなので、1回くらい実験しても 損はないでしょう^^FはFlashですし。 あと、インタープリターや二モニックテスターで 動作確認してみるのも手ですね。 私が使ってた頃の、PICってスタックがそうじゃなくて ハードウエアスタックって言う、割り込み専用のが ついてたので、そもそも、戻りアドレス(セグメントと) しかなかったですからね~数も固定で4~8程度 なので、ちょっと今のPICはわからないかなって所です。 後半Scenixに浮気したもので(笑)今はもうなくなりましたけどね。 高速互換PICチップ。。

natukun1234
質問者

お礼

遅れましたがご回答ありがとうございます。

関連するQ&A

  • PIC16F84のプログラム

    PIC16F84のプログラムでこのようなものを作りました。 revel1   movlw 75        movwf tm3        movlw 255        movwf tm4 no1_on   mov rb,#11110000b     ;(1)        mov rb,#10000000b        mov rb,#11000000b        mov rb,#10100000b        mov rb,#11000000b        mov rb,#10000000b    ;(2)        decfsz tm4,1        goto no1_on        decfsz tm3,1        goto no1_on これは、(1)~(2)の動作を75×255=19125回(多分)繰り返すという物です。 同様の処理を多数行ないたいのですが、プログラムしてみたところ、容量オーバーの為か?アセンブルできませんでした。これを同様の動作でもう少しシンプルに出来ないでしょうか?よろしくお願いします。

  • PICのSleepからの復帰に関して

    INTピンを使ってsleepから割り込み復帰したいのですが、 思ったとおり動いてくれません。 メインをSLEEPにし、割り込みが入ると割り込み側の プログラムを実行し、終わるとメインのSLEEPに もどってINTの割り込みに備えるようにしたいのです。 現段階では割り込みをするとSLEEPから割り込み には行くのですが、そのまま割り込み側のプログラムを 永遠に繰り返してしまいます。 list p=12f629 include p12f629.inc RELOOP1 equ 0x20 CT_DELAYNMS equ 0x21 PCLATH_TEMP equ 0x2a W_TEMP equ 0x2b STATUS_TEMP equ 0x2c stu equ 0x2d org 0x0 goto start org 0x4 ;レジスタの退避 movwf W_TEMP swapf STATUS,W clrf STATUS movwf STATUS_TEMP movf PCLATH,W movwf PCLATH_TEMP clrf PCLATH ;割り込み要因のチェック btfss INTCON, INTF goto INT_NEXT1 ;ここから割り込みプログラム 省略 INT_NEXT1 ;レジスタの復帰 movf PCLATH_TEMP,w movwf PCLATH swapf STATUS_TEMP,W movwf STATUS swapf W_TEMP,F swapf W_TEMP,W retfie ;初期設定 start: ;aLED単独の輝度 bcf STATUS, RP0 clrf INTCON clrf GPIO bsf STATUS, RP0 clrf OSCCAL clrf TRISIO bsf TRISIO,2 movlw B'01000101' movwf OPTION_REG bcf STATUS, RP0 ;割り込み許可する movlw B'11010000' movwf INTCON nop sleep nop goto $-3 end こんな感じのプログラムなのですが、INTピンからの割り込みと いうことでプリスケーラなどは使っていません。 データシートも読んだのですが今市理解ができていない状況です。 お願いします。

  • PIC16F84Aのプログラムについて(初歩的な質問)

    PICのプログラムを勉強しています。簡単なプログラムとして電源を入れるとPORTBにつないだLEDを3回点滅させて、最後は点灯しっぱなし(電源きるまで)にしようとしていますが、点灯しっぱなしにならずにずっと点滅してしまいます。(プログラムの最初に戻ってるらしい)昔のBASICなどですと「100 GOTO 100」とかすると変数の値はそのままで無限ループするので、PICでもSTATUSレジスタのPORTBを1にする命令を何回もGOTOによって繰り返させてますが出来ません。何故でしょうか?PORTBを電源切るまで1にしたままにするにはどうすればいいのでしょうか?勉強不足で私自身何もわかってませんがよろしくお願いいたします。

  • PIC18F2550でのUSARTの使い方について

    フリーのC18コンパイラで電子工作をしています。 今回18F2550でシリアル通信に挑戦していますが、自分の目的の動作のためのレジスタ設定が理解できません。教えて下さい。 動作内容はPICからシリアル通信でデータを送り12ビットシリアル-パラレル変換の「NJU3714」でシリパラ変換させることです。PICのデータ受信は今のところしないつもりです。

  • PIC 16F54 でTMR0割り込みを使いたい。

    最近PICによる電子工作を学び始めた初心者です。 値段が安いことにひかれて 16F54 を使っていろいろ学んでいこうと思ったのですが、TMR0割り込みを使ったプログラムを組もうとしたところ、行き詰まってしまいました。 他の 16F84A やその他のネットで紹介されている PIC の場合、INTCONレジスタのT0IEをセットしたり、T0IFをクリアにしたり、RETFIEで元の位置に戻ったりすると思うのですが、16F54にはINTCONレジスタも RETFIE命令もありません。 試しに、MPLABでINTCONレジスタの設定は無しにして、RETFIE命令は書き込んでアッセンブルしてみたらRETFIE命令に警告が出たものの、どうにか成功しました。 そこで試しにデバックしてみると、T0IEをセットしていないので当然なのですが、TMR0はカウントされるものの、割り込みは発生しませんでした。16F84Aや16F88等のPICも数百円で買えるので素直にこれらをチョイスすれば良いのでしょうが、百円を切る低コストの16F54に魅力を感じるし、何より疑問を解決しないまま、財力に任せて解決とすることに抵抗があります。 どなたかこんな私を助けてください。

  • PIC12F629の発振

    PIC12F629を外部に某社のセラロックを使って XTモードで4MHzで発振しています。 (今回は内部発振は精度上使えません。) しかしCLKOUTの出力スィングは01.7V しかありません。 ただしプログラムは正常に動作しています。 同様のことをPIC16F84Aでやると CLKOUTの出力スィングは04Vあります。 CLKOUTの出力スィングが小さいことは 問題ないのでしょうか。 ただPIC12F629をHSモードにするとスィングは 05VありますがCLKOUTの波形の 歪は大きくなります。 プログラムは正常に動作しているといっても試作の 3セットだけなので量産したときのことを かんがえるとやや不安です。 どう考えたらよいかアドバイスください。

  • PIC16F88 動作不良

    PIC初心者です。 PIC16F88を使用してスイッチ入力(Aポート)でAポートでリレーとBポートでスイッチのLEDの制御をしていました。 全16台中1台のみスイッチのLEDが点灯したまま動作しなくなりました。 電源を再投入しても復帰しません。 秋月電子のROMライターで、データーを読み込み、別のPIC16F88に書き込み、同基板にセットして電源を入れると、正常に動作します。 不具合のPICは再書き込みすると、動作してしまい原因がわからなくなりそうなので、再書き込みはしていません。 何が原因(考えられる要因)かわかる方、よろしくお願いします。

  • PIC16F84 10進-->2進変換プログラム

    いつもお世話になっております。 google等で検索して居りますが行き詰まってこちらに投稿させて 頂きました、何卒宜しくお願いいたします。 PICマイコン 16F84などを使った制御を行っていますが下記の アセンブラプログラムが書けなくて苦慮して居ります。 10進-->2進変換 具体的には・・・・ 10進(0~9)二桁のデジスイッチをRB0,1,2,3のポートにダイオードOR にて接続して設定値00~99までのどれか一つの数字をレジスタに読み 込ませます、一度設定したら少なくとも数日はそのままです。 例えばデジスイッチを63に設定すればレジスタにも63と読み込まれ ますがPICマイコン側から見れば10進の63では無くてそれは16進の63H だと当然判断されます、これを2進変換して3FHに書き替えたいのです。 デジスイッチ設定値63 0110 0011 ↓↓↓↓ 3FH 0011 1111 デジスイッチ設定値50ならば 0101 0000 ↓↓↓↓ 32H 0011 0010 デジスイッチ設定値99ならば 1001 1001 ↓↓↓↓ 63H 0110 0011 原始的に引き算を繰り返す事で00から99までのプログラムを書きましたが 大変冗長的で他に既知のプログラムが有るのではないか、例えばBit反転 して幾つを足すとか引くとかそのような簡単なプログラムが有れば是非 ご教示頂きたいと存じます。 16進(0~F)のデジスイッチならこの様な変換は無用なのですが人間 が相手なのでどうしても10進デジスイッチを使うことを要求されます。 初歩的な質問ですがどうか宜しくお願いいたします。

  • PIC16F874Aについて

    16F874Aを使用して回路をつくっているのですが、I/Oピンの出力(LEDを接続)はちゃんと動作してくれるのに、入力(スイッチを接続)が全く動作してくれません。動作確認のために、 void main(){ PORTB=0x01; TRISB=0x01; while(1){ if(PORTB.F0==0){ PORTB.F1=1;     } }        } という簡単なプログラムでも動作しません。 また、AN0~AN7をデジタルで使用したいため、A/D変換のプログラムとして、 setup_adc_ports(0b00000000); をプログラム中に入れてビルドすると、エラーが出てしまいます。 PIC素人のため初歩的な質問かとは思いますが、回答よろしくお願いします。

  • PIC16F84Aから16F628Aの変換について

    以前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