目次PIC回路集リモコン


無線リモコン受信機 処理説明



環境設定
    送信機のソフトウェアと同じで、リストの行番号008-011で各種の環境設定をしています。

    008
    list
    使用するPICの名称を定義しています。
    009
    include
    各種の標準ラベルが定義されているファイル(p16f84a.inc)の組み込みを指示しています。
    010
    __config
    コンフィギュレーションワードの指定をしています。
    _hs_osc発振器の種類:HS
    _wdt_offウォッチドッグタイマー:使用しない
    _pwrte_onパワーアップタイマー:使用する
    _cp_offコードプロテクタ:使用しない
    上記の指定によるコンフィギュレーションワードの値はH'3FF2'です。


    011
    errorlevel
    バンク切り替え警告メッセージ[302]の表示が出ないようにしています。
    PIC16F84AのRAMファイルレジスタはバンクという方式を使用しています。例えばTMR0もOPTION_REGも01番地にあり、TMRはバンク0、OPTION_REGはバンク1です。INCLUDEで読み込む定義ファイルではOPTION_REGのアドレスをH'0081'と定義していて、バンク情報も書かれています。しかし、実際の処理ではSTATUSレジスタのRP0ビットによりバンクを指定する必要があります。MPLABではバンク切り替えを間違えないようにバンク1のレジスタの処理があると警告メッセージ"Message[302]"が表示されます。
    Register in operand not in bank 0. Ensure that bank bits are correct.
    「オペランドで指定されたレジスタはバンク0ではありません。バンク指定ビットが正しいか確認しなさい。」という内容です。バンク指定を正常に行っていてもこのメッセージは表示されます。このメッセージを出さないようにするためには定義ファイルの指定を変えてしまう方法があります。すなわち、OPTION_REGのアドレスをH'0001'と変えることにより、メッセージは表示されなくなります。または、今回使用しているようにERRORLEVEL命令を使って302のメッセージの表示を止める方法があります。




ラベル定義
;****************  Label Definition  ********************
    RAMレジスタファイルに領域を確保する部分にはCBLOCKおよびENDCを使用しています。これらのコマンドに挟まれたラベルはCBLOCKで指定しているアドレスから順番に領域が自動設定されます。
    ptn1およびptn2は制御コードデータを指定するラベルです。ここで指定する値は送信する制御コードと一致させておく必要があります。
    RX_STATUS 受信状態を管理するエリア
    0:プリアンブルコード受信状態、1:制御コード受信状態、2:終了コード受信受信
    RX_SUBSTATUS 受信状態を管理するエリア
    上記の各状態で、受信ビット毎の状態管理をします。
    RX_EDGE 電波立ち上がり検出要求フラッグ
    送信機からの制御コードを受信している最中に異常状態を検出した場合、このフラッグがONします。フラッグONを検出すると電波の立ち上がり検出から行われるようになります。
    LAST_LOOK ラストルックフラッグ
    電波の立ち上がりを検出するためには電波を検出していない状態から電波を検出したことを認識できなければいけません。電波の状態を表す入力ポート(RA1)をチェックしたとき電波が受信されていない状態をこのラストルックエリアに記憶します。RA1ポートで電波を受信したときラストルックエリアと比べれば電波の立ち上がりが分かります。
    CODE_CK コードチェックフラッグ
    受信機は出力リレーの動作時間を確保するために常に10ミリ秒のタイマーを動作させています。このタイマーを使って受信コードのチェックもするので、コードのチェック処理を行うかどうかをこのフラッグで制御します。電波の受信するとフラッグをONにします。
    CONT_DATA 制御データ格納エリア
    制御データは1ビットづつ受信されます。ビットを受信する毎にこのエリアに格納します。
    RELAY リレー動作時間カウントエリア
    出力リレーを動作させた場合、約500ミリ秒間動作させるようにしています。リレーを動作させるとき、このエリアに50を設定します。この値は10ミリ秒のタイマーで減算し、0になった時点でリレーの動作を停止します。
    W_SAVE Wレジスタ待避エリア
    タイマー割込が発生したとき、割り込まれた処理で使用しているWレジスタをこのエリアに待避します。
    S_SAVE STATUSレジスタ待避エリア
    タイマー割込が発生したとき、割り込まれた処理で使用しているSTATUSレジスタをこのエリアに待避します。




プログラム開始
;**************** Program Start ***********************
    プログラムメモリアドレス0番地は電源投入時またはリセットが発生した場合のプログラム実行開始アドレスです。また、4番地はタイマー割り込みなどの割り込み処理が発生した場合の開始アドレスです。これらのアドレスはPIC16Fシリーズではハードウェアで決まっていて変えることはできません。




初期化処理
;****************  Initial Process  *********************
    ポート初期化
      まず、ポートの初期化を行います。RA0からRA4を入力モード、RB0からRB7を出力モードに設定しています。
      配線の関係でRA0とRA3を接地しています。そのため、RA0とRA3は必ず入力モードにする必要があります。

    タイマー設定
      今回の回路ではデータの切り替え時間は10ミリ秒です。10ミリ秒の時間はタイマー0を使用して作ります。タイマー0に内部クロックおよびプリスケーラを使用するためにOPTION_REGのTOCSおよびPSAを"0"にします。プリスケーラ値は"101"で1:64にしています。PICの発振器には4MHzを使用しているのでクロックは1μ秒になり、プリスケーラと組み合わせてTMR0のカウントアップクロックは64μ秒です。TMR0はカウントアップタイマーでカウント値(TMR0)が255(H'FF')から0になるとタイマー割り込みが発生します。ですから、10ミリ秒のタイマーを設定するためには256-(10000/64)=100になり、タイマー設定処理でTMR0に100を設定すれば良いことになります。送信機と受信機のタイマー誤差を少なくするため、送信機と同じプリスケーラ値を使用します。

    レジスタ値の初期化
      PICの電源を入れた場合には各種のレジスタは初期化されていますが、念のためにレジスタの初期化をしています。
      PROTB= 0出力リレーの動作を停止します。
      RX_STATUS
      RX_SUBSTATUS
      = 0
      = 0
      受信管理エリアの初期化をします。
      RX_EDGE= 0電波立ち上がり検出要求フラッグをクリアします。
      LAST_LOOK= 1ラストルックを電波受信状態(ON)に初期化します。
      CODE_CK= 0制御コードのチェック処理をしない状態にします。
      CODE_DATA= 0制御データ格納エリアを初期化します。
      RELAY= 0リレー動作カウンタをクリアします。

    10ミリ秒タイマー設定
      リレーの動作時間を管理するために10ミリ秒タイマーを起動します。




初期受信処理
;*********** Initial Input check Process **************
    RA1ポートの状態により電波の受信状況をチェックします。電波を受信していないときにはラストルックフラッグ(LAST_LOOK)をOFFにします。この処理は無駄に思われるかもしれませんが、電波の立ち上がり時点を検出するためには電波が一度無くなったことを確認する必要があります。また、連続した電波で誤動作することを防いでいます。ラストルックフラッグがOFFで電波を検出すると電波の立ち上がりを検出したことになります。送信機からのパルスは10ミリ秒間隔で切り替わります。ですから、受信側では電波の立ち上がりから5ミリ秒ずらしたところから10ミリ秒間隔で信号の検出をさせます。タイマーとしてはTMR0を使い、リレー動作時間管理用と同じです。基本的には初期化処理で10ミリ秒周期で動作させています。電波の立ち上がりを検出した時点でこのタイマーを強制的に5ミリ秒に再設定します。そのため、この再設定処理の間にタイマー割込が発生しないように、まず、割込禁止にしています。(INTCON.GIE=0) そのあと、コードチェックフラッグ(CODE_CK)をONにしてタイマー処理にコードチェック処理をさせます。電波の検出をしたので、ラストルックフラッグをONにします。TRM0に5ミリ秒のタイマーを設定したあと割込を可能にします。このあとはタイマー割込を待つ処理になります。割込待ちの処理では電波立ち上がり検出要求フラッグのチェックをします。制御コードの検出処理で異常を検出した場合、このフラッグをONにします。割込待ち処理でこのフラッグのONを検出するとフラッグをクリアしたあと、電波の立ち上がり検出処理にジャンプし、受信動作は初期状態に戻ります。




タイマー割り込み処理
;************  Timer Interruption Process  **************
    レジスタの待避
      タイマー割込処理では最初にWレジスタとSTATUSレジスタの待避を行います。割込前の処理でこれらのレジスタを使用している場合、割込処理でレジスタの内容が変わると処理ができなります。今回の処理では割込前の処理でWレジスタを使用していないので、待避する必要はありません。念のため入れました。他のレジスタも共用するものがあれば待避する必要があります。メモリバンク指定も念のために設定しています。

    タイマー割込フラッグのクリア
      割込が発生すると割込要因によって割込種別を表すフラッグが設定されます。これにより何の割込が発生したかを知ることができます。タイマー0割込が発生するとINTCON.T0IFビットに1が設定されます。このビットは割込処理でクリアする必要があります。クリアしないと、割込要因が消えず、また、同じ割込が発生してしまいます。

    出力リレーカウンタのチェック
      出力リレーを動作させたあと、約500ミリ秒間動作を持続するようにしています。その時間を監視するためにリレー動作カウンタ(RELAY)の値を減算します。カウンタ値が既に0の場合はリレー制御をしていないということでカウンタ処理は行われません。カウンタが0でなく、減算した結果で0になった場合、リレーの動作を停止します。

    受信ステータスのチェック
      RX_STATUSの内容によりチェックする内容を判断します。0の場合はプリアンブルコードのチェックをします。1の場合は制御コードのチェックをします。2の場合は終了コードのチェックをします。

;*********** Preamble data check Process *************
    プリアンブルコードのチェック
      プリアンブルコードは101010110です。設計当初は10の連続を検出し、11でプリアンブルの終了判断をするようにしていました。しかし、最終的にはプリアンブルコードの並びが全て一致している場合に正常なプリアンブルコード受信と判断するようにしました。10110というビット列が制御コードにもあり得るからです。例えばB0=1,B1=1の場合にB0の位置から受信すると同じビット列になります。しかし、B0の前は必ず1なので電波の立ち上がり検出は行われず、上記のような誤動作はしません。しかし、処理を変更してしまったので全ビットの並びをチェックすることにしました。各ビットの受信管理はRX_SUBSTATUSで行います。正常なプリアンブルコードを受信するとRX_STATUSを1にして制御コード受信に移ります。このとき、制御データ格納エリア(CODE_DATA)をクリアして、前に受信した制御コードを消しておきます。ビット列の異常を検出するとイリーガル処理にジャンプします。

;************ Control data check Process **************
    制御コードのチェック
      制御コードの構成は1x01x01x01x01x01x01x01x0です。xには制御コードのビットが入ります。全部で8ビットになります。このビット列を順番にチェックし、xの部分を制御データ格納エリア(CODE_DATA)に格納します。正常な制御コードを受信するとRX_STATUSを2にして終了コード受信に移ります。ビット列の異常を検出するとイリーガル処理にジャンプします。

;************** End data check Process ****************
    終了コードのチェック
      終了コードは111です。RX_STATUSが2の状態で1が3回連続受信されると正常な終了コードと判断し、制御データのチェック処理に移ります。終了コードが異常な場合、イリーガル処理にジャンプします。

;**************** Data check Process ******************
    制御データのチェック
      制御データチェック処理ではパターン1のデータとパターン2のデータのいずれかと一致するかどうかを確認します。これらのパターンは当然、送信機のパターンと一致させておく必要があります。パターン1と一致した場合にはリレー1を動作させ、リレー2を非動作にします。パターン2と一致した場合にはリレー1を非動作させ、リレー2を動作にします。そして、いずれかのリレーを動作させたあと、500ミリ秒の保持時間のためリレー動作時間カウントエリア(RELAY)に50を設定します。この値は10ミリ秒毎に減算され、500ミリ秒後にリレーの動作が止まります。制御データがいずれのパターンとも一致しない場合でも正常にリレーを駆動した場合でもイリーガル処理に移ります。正常な場合でもイリーガル処理をさせるのは、次のコードを受信するときの受信タイミングを電波の立ち上がりで再設定させるためです。



イリーガル処理
;*****************  Illegal Process  ********************
    受信するコードが規定された並びでない場合、全てのデータが正常に受信された場合にこのイリーガル処理が実行されます。イリーガル処理では以下の処理が行われます。
    電波立ち上がり検出要求フラッグ(RX_EDGE)を設定し、これにより電波の立ち上がり検出が行われます。受信状態管理(RX_STATUS,RX_SUBSTATUS)をクリアし、プリアンブルコードからの受信をするようにします。コードチェックフラッグ(CODE_CK)をクリアし、10ミリ毎のタイマー処理で制御コードチェック処理をスキップするようにします。その後、割込終了処理に移ります。



サブステータス更新処理
;***********  Substatus Increment Process  **************
    各受信状態(プリアンブル、制御コード、終了コード)で検出ビットの位置を管理するためにサブステータスを使っています。1ビット受信する都度、サブステータスを1つ加算して更新します。その後、割込終了処理に移ります。



タイマー割り込み終了処理
;********  End of Timer Interruption Process  ***********
    タイマーの割込終了はこの処理で行われます。
    まず、10ミリ秒のタイマー値をTMR0に設定して次回のタイマー割込を10ミリ後に行わせるようにします。そのあとにWレジスタとSTATUSレジスタの復元をします。最初にSTATUSレジスタを復元します。これはSTATUSレジスタの復元処理でWレジスタを使うので、最初にWレジスタを復元するとWレジスタの内容が復元値と変わってしまうためです。最後にWレジスタを復元しますが、MOVF命令を使ってWレジスタを待避エリアから読み出すとSTATUSレジスタの内容が変わってしまいます。そこでSTATUSレジスタの内容が変わらないSWAPF命令を使用してWレジスタの復元をします。最後にRETFIE命令で割込処理を終了します。この命令を実行するとスタックエリアに待避されていた割込戻り番地にジャンプし、さらにINTCON.GIEビットに1が設定され、割込が可能な状態になります。