PIC16F84AのRBポート変化割り込みの使い方

このQ&Aのポイント
  • PIC16F84AのRBポート変化割り込みを使いたいのですが、割り込み処理のRBIFフラグの解除方法や、RBポートのプルアップについて疑問があります。
  • RBポートを外部に抵抗をつけてプルアップした場合でも、正しくシミュレーションできるのでしょうか?
  • RBポート変化割り込みは、LからHになった場合と、HからLになった場合の両方に反応するのでしょうか?
回答を見る
  • ベストアンサー

PIC16F84AのRBポート変化割り込みの使い方

PIC16F84AのRBポート変化割り込みを使いたいのですが、三つ質問があります。 1.割り込み処理に入ったときに、「BCF INTCON,RBIF」としてもRBIFフラグが立ったままで、「RETFIE」で割り込みから戻った直後にすぐにまた割り込み処理に入ってしまいます。(MPLABのシミュレーション上でStimulusControlerでPINを変化させて実験)これの原因は何なのでしょうか?RBIFフラグはどのようにして解除したらよいのでしょうか? 2.RBポートは内部でプルアップせずに、外に抵抗をつけてプルアップしようと考えているのですが、その場合でも正しくシミュレーションできるのでしょうか? 3.RBポート変化割り込みは、LからHになった場合と、HからLになった場合の両方に反応するのでしょうか? 以上三つの質問に回答お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • macky_
  • ベストアンサー率60% (3/5)
回答No.1

ソースが無いので実装が分かりませんが。 1 と 3 は下記のサイトで解決するように思います。 http://www.picfun.com/pic08.html 2 はすいませんが分かりません。

参考URL:
http://www.picfun.com/
minimax2005
質問者

お礼

回答ありがとうございます。 「BCF INTCON,RBIF」の前に「NOP」をいくつか入れてみたら、なぜかフラグをクリアできました。 その他の問題も一応解決することができました。

関連するQ&A

  • PIC12F675のRB割込みミス(?)

    PIC12F675を20MHzでポート変化割込みを使用しています。 A.割込みルーチン内では BTFSC 05.3とラストリードし、bit出力(オシロでのチェック用)をするのみ (ポート変化割込に使用しているbitへの入力は約500Hz) B.メインルーチン内では MOVWF 05という形で無限ループでGPIOに出力し続けるのみ。 (出力周期は約600KHz) オシロでみると、入力が変化しても割込みが発生しないミスがかなりあります。 ここでB.の出力にディレイを入れて出力周期を約1KHzに下げると割込みミスは減少します。 Q1. マニュアルによれば、ポート変化割込みはラストリードから入力が変化とき 発生するとあります。 ラストリードはA.の割り込みルーチン内でしかしていません。 したがってB.で出力しても(出力にBCF,BSFは使用していません) 割り込みの発生には関係ないはずですが 現実は出力周期が割り込みの発生に大きく関係しています。 どういう理由でしょうか? Q2. ここまで述べてくると PIC12F675では、ポート出力をしているときはポート変化割込み ミスがある???ということになってしまいます。 これは正しいのでしょうか? 入力の変化を見落とさないために、ソフトウェアプログラムではなく割り込みを使用しているのですが・・・。

  • 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に魅力を感じるし、何より疑問を解決しないまま、財力に任せて解決とすることに抵抗があります。 どなたかこんな私を助けてください。

  • PIC アセンブラ ポートB 内部プルアップ抵抗の使い方

    PIC16F877Aを使っています。 プログラムを作り始めてかなりたってから ポートBにプルアップ用の抵抗があることを知りました。 それで使い方とか調べてみたんですが ポートBで内部プルアップを使う場合は RBを全部入力設定にしないといけない的な事を 書いてるページがありました。 これって、そうしないとPICが壊れてしまうって事でしょうか? RB0~RB3にタクトスイッチ(入力) RB4~RB7に7セグのカソード(出力) として入出力を混ぜて使いたいのですが スイッチ用にポートBをプルアップ抵抗ONにしても問題ないでしょうか?

  • PIC12F683 TMR2の割込がうまくいきませ

    タイトルのPICを使ってTMR2の割込動作を確認しているのですが、割込が全く掛かりません。 TMR2は単独で割込を掛けないで動作することは確認できましたがエラーもあるわけでもなく あれこれやっても解決せず迷走中です。また、割込ルーチンはこれまで動作が確認できたプログラムを埋め込んで使っているので問題はないと思っています。 何方かお助け頂けませんでしょうか。宜しくお願い致します。 ;******************************************* ; PIC初期設定 ;******************************************* START_INI BCF STATUS,RP0    ;BANK【0】 MOVLW 07h MOVWF CMCON0 ;GP0-2はデジタルIO BSF STATUS,RP0    ;BANK【1】 MOVLW B'0000000' MOVWF ANSEL ;A/D変換クロックF/2 デジタルI/O BCF OPTION_REG,7 ;GPIO端子をプルアップ MOVLW B'001000' ;RESET端子有効 MOVWF TRISIO ;GP0,1,2,4,5:OUT GPO3:IN MOVLW B'1000000' ;40h MOVWF OSCCON ;クロック=1MHz ;******************************************* ; TMR2の設定 ;******************************************* BCF STATUS,RP0    ;BANK【0】 MOVLW B'000101' ;ポス=1:1 TMR2=ON プリ=1:4 MOVWF T2CON ; BCF PIR1,TMR2IF    ;Timer2 割込み検出フラグをクリア BSF STATUS,RP0    ;BANK【1】 BSF PIE1,TMR2IE    ;Timer2 有効 MOVLW H'FA' ;250 MOVWF PR2    ;TRM2カウントSET ;******************************************* BCF STATUS,RP0     ;BANK【0】 CLRF TMR2 BSF INTCON,GIE     ;割り込み全体を有効

  • 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

  • pic 16f84a割り込み処理について

    pic cともに初心者です。 至らないところなどございますが、よろしければご教授くださいm(__)m 現在pic 16f84aで、電球の明るさ(交流100v)を決まったタイミングでフェードインフェードアウトさせる回路を製作しています。 コンパイラはccs社のpcm、MPLAB使用です。 基本的なプログラムの構成についての疑問です。 まず (1)インターバルタイマを使用し、タイマを10msec(約)に再セット。 変数icount で秒数をはかり、 メイン関数では、それを元にduty という変数(0-255)を変化させます。 #int_timer0 void intval(){ set_timer0(0x3c); icount++; } その処理に平行して (2)ゼロクロスパルスの割り込みをRB0への入力から発生させます。 RB0にはハードから入力(H_to_L)がはいるように出来ており これも10msec毎です。 #int_EXT void isr(){ int i if((duty > 10) & (duty < 250)){ delay_us(200); for(i = 0; i <(255-duty); i++){ delay_us(38); output_low(PIN_C5); delay_us(100); output_high(PIN_C5); } else{ if(duty <= 10){ output_high(PIN_C5); } else{ output_low(PIN_C5); }} メイン関数では duty を icount(時間)によって、変化させる関数を書きます。 25秒かけて、消灯状態から(duty= 0)点灯(duty = 255)まで スムーズに変化させます。 疑問点は 上記の二つの割り込みは、ともに10msec 毎で、(2)の割り込みに至っては いちど割り込むとdelay が多いので10msecの間ほとんど割り込み禁止です。 こういう場合でも、問題なく二つの割り込みは動いてくれるのでしょうか?(1)のカウントがある程度正確に動いてくれないと、秒数が狂ってしまうので、不安です。 また、この段階で、考え方そのものが間違っていないかも わかりません。 よろしければ、ご意見などいただけると幸いです。 なにとぞ、よろしくお願いいたします。

  • PIC16F84Aで出力が反転してしまう

    PIC16F84Aを用いて、矩形波を出そうとしています。 下記のようなプログラムを動かそうとしているのですが、 PORTA,1をONした時、出力がすべて反転してしまいます。 原因はどのような事が考えられますでしょうか? PORTA,0:矩形波の波長 PORTA,1:入力トリガが立ち上がりか立ち下がりか? PORTA,2:矩形波を立ち上がりにするか、立ち下がりにするか? PORTA,3:LED用出力 PORTA,4:手動トリガスイッチ PORTB,4~7:出力 で行っています。 ラベルL_Hの所で、出力はBCFで0になっているはずですが、 すべて1出力になります。 トリガを入れた時の出力も反転された状態になります。 ----------------------- LIST P=PIC16F84A ; LIST宣言で使用するPICを16F84Aと定義する。 INCLUDE P16F84A.INC ; 設定ファイルp16f84a.incを読み込む。 __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF ; ;変数の設定(タイマ用カウンタ)********************* CNT1 EQU 0CH CNT2 EQU 0DH CNT3 EQU 0EH CNT4 EQU 0FH CNT5 EQU 10H CNT6 EQU 11H ;リセット************** ORG 0 ;リセット ;初期設定************* CLRF PORTB ;PORT-Bをオール0 BSF STATUS,RP0 ;バンク1へ MOVLW B'00001111' ;00001111 MOVWF TRISB ;PORT Bを0-3を入力、4-7を出力として設定 MOVLW B'10111' ;00010111 MOVWF TRISA ;PORT Aを0-3を入力、4を出力として設定 NOP BCF PORTB,4 ;PORTB,4~7をオール0 BCF PORTB,5 ;PORTB,4~7をオール0 BCF PORTB,6 ;PORTB,4~7をオール0 BCF PORTB,7 ;PORTB,4~7をオール0 BSF PORTA,3 ;PORTA,3を1 CLRF CNT1 CLRF CNT2 CLRF CNT3 CLRF CNT4 CLRF CNT5 CLRF CNT6 ;入力が1か0か?************************ Trig_Direc NOP BTFSS PORTA,1 ;入力判定が立ち上がりの時 GOTO Diec_Hight GOTO Direc_Low ;入力立ち上がり、出力判定******************* Diec_Hight BTFSS PORTB,2 ;連続波出力の時 GOTO H_Comti BTFSS PORTA,2 ;出力判定が立ち上がりの時 GOTO H_H ;入力立ち上がり、出力立ち上がり GOTO H_L ;入力立ち上がり、出力立ち下がり ;入力立ち下がり、出力判定***************************************** Direc_Low BTFSS PORTB,2 ;連続波出力の時 GOTO L_Comti BTFSS PORTA,2 ;出力判定が立ち上がりの時 GOTO L_H ;入力立ち下がり、出力立ち上がり GOTO L_L ;入力立ち下がり、出力立ち下がり ;入力立ち上下がり、出力立ち上がり トリガ入力判定と出力************ H_H BCF PORTB,4 ;Trig出力1 OFF BCF PORTB,5 ;Trig出力2 OFF BCF PORTB,6 ;Trig出力3 OFF BCF PORTB,7 ;Trig出力4 OFF BSF PORTA,4 ;LED点灯 off ~正常出力 ・ ・ ・ ;入力立ち上下がり、出力立ち上がり トリガ入力判定と出力*************** L_H BCF PORTB,4 ;Trig出力1 OFF BCF PORTB,5 ;Trig出力2 OFF BCF PORTB,6 ;Trig出力3 OFF BCF PORTB,7 ;Trig出力4 OFF BSF PORTA,3 ;LED点灯 off L_H_ON BTFSS PORTB,0 ;トリガ入力1に入力があった場合 GOTO L_H_Time BTFSS PORTB,1 ;トリガ入力2に入力があった場合 GOTO L_H_Time BTFSS PORTA,4 ;手動トリガ入力に入力があった場合 GOTO L_H_Time GOTO Trig_Direc ;トリガ入力がなかった場合、初期判定に戻る L_H_Time BCF PORTA,3 ;トリガ判定LED点灯 BTFSS PORTA,0 ;パルス幅が50ms指定の場合」 GOTO L_H_50 GOTO L_H_200 L_H_50 BSF PORTB,4 ;Trig出力1 ON BSF PORTB,5 ;Trig出力2 ON BSF PORTB,6 ;Trig出力3 ON BSF PORTB,7 ;Trig出力4 ON CALL Timer_50ms BCF PORTB,4 ;Trig出力1 OFF BCF PORTB,5 ;Trig出力2 OFF BCF PORTB,6 ;Trig出力3 OFF BCF PORTB,7 ;Trig出力4 OFF CALL Timer_50ms GOTO L_H_Loop L_H_200 BSF PORTB,4 ;Trig出力1 ON BSF PORTB,5 ;Trig出力2 ON BSF PORTB,6 ;Trig出力3 ON BSF PORTB,7 ;Trig出力4 ON CALL Timer_200ms BCF PORTB,4 ;Trig出力1 OFF BCF PORTB,5 ;Trig出力2 OFF BCF PORTB,6 ;Trig出力3 OFF BCF PORTB,7 ;Trig出力4 OFF CALL Timer_200ms GOTO L_H_Loop L_H_Loop BTFSC PORTB,0 ;トリガ入力1が出力状態だった場合 GOTO L_H_Loop BTFSC PORTB,1 ;トリガ入力2が出力状態だった場合 GOTO L_H_Loop BTFSS PORTA,4 ;手動トリガ入力に入力があった場合 GOTO L_H_Loop BSF PORTA,3 ;トリガ判定LED消灯 GOTO Trig_Direc ;初期へ戻る ・ ・ ・ 以下略

  • PIC16F1827のEEPROMへの書込み

    PCM V5.0(PIC用CCS社コンパイラ)を Mplab8.92に組込み、PICkit3を使ってプログラムしています。 PIC16F1827のEEPROMへの書込みがうまくいきません。 RAは入力ポートで固定してあります。 RBは出力ポートでLEDが接続してあります。 テストプログラムは一回のみの動作です。 実機で動作させると RAは固定してあるので当然(4)でLEDが点灯しますが、 実機からCPUを抜き取りMplab上でReadすると EEPROMのアドレス0,1,2は異なるデータであり 動作させるたびに違うデータが書込まれています。 しかし (1) a0=35h (2) a1=a6h (3) a2=93h と定数にすると EEPROMのアドレス0,1,2は正しいデータが 書込まれています。 Q1. a0,a1,a2をポート入力とする場合は CPU自体に何か設定する必要があるのでしょうか? それともプログラムに工夫が必要なのでしょうか? いままで使っていたPIC16F88では このようなことはなかったと思うのですが・・・。 ----- テストプログラム ----- a0 = RA; //(1) write_eeprom (0,a0); a1 = RA; //(2) write_eeprom (1,a1); a2 = RA; //(3) write_eeprom (2,a2); if (a0 == a1 && a1==a2) //(4) RB =255; else RB =0;

  • PICの割り込みフラグについて

    PIC18F4550を使用して、RB0とRB1への入力の立ち上がり、立下りエッジを検出しようとしています。 素直に割り込み処理へ入れば実現できるのですが、他の処理との兼ね合いの問題もあり、出来れば割り込みを使用したくありません。 そこで思ったのですが、割り込みを禁止にしていても、各割り込みフラグは変化するのでしょうか? 回答よろしくお願いします。

  • PIC12F675 GPIO入出力について

     現在、PIC12F675にてA/D変換、EEP- W/R,TMR0を使ったプログラムを作成しているのですが、GPIOの入出力がおかしくTMR0、GP0~2が正常に動作しません。   ●各PINの使用状況・・・ ・GP0/出力(H/L) ・GP1/出力(H/L) ・GP2/TMR0 ・GP3/入力(S/W) ・GP4/入力(A/D変換) ・GP5/出力(H/L) ●開発環境   ・MPLAB IDE V8.40   ・デイバイス PIC KIT1 MPLAB IDEのファイルレジスタとウォッチのウインドウでデバッグしていて気づいたのですが、SFRアドレス00H~05Hまでの変化がそのままGPポートの変化へとつながっており、GP0がRestricted Memoryicted Memoryが表示され、SIMでRUNさせてみるとプログラムでは「BSF」でGP0を出力してもGPIOの0ビット目は変化しません。 GP2も変化がなくTMR0も動作していない様です。  もちろんBANK1でTRISIOの設定(B'00011000')は行っています。 自己解決を試みましたが万策尽きて投稿させていただきました。 恐れ入りますが何方かご教授いただけましですでしょうか。  

専門家に質問してみよう