ローエンドな私とマイコン

小技
MPASMの小技の紹介

1.GOTOとCALLの違い
 一般的なマイコンでは2つ命令でアドレス指定を気にしてプログラムを組むことはあまりないと思いますが、PICマイコンに関しては重要な要素となります。
BASETYPEに限りますが、GOTOでは全アドレスが対象になりますが(9ビット+ページビット)、CALL命令のアドレスは8ビット+ページビットになり9ビット目には0が入ります。つまりページの先頭から256ステップ(0xFF)が有効アドレスになります。BASETYPEは512ステップを1ページで管理しているので前半部分にしかサブルーチンを配置できないのです。
 しかし手はあります、GOTOでは512ステップをジャンプできるので、アドレス前半部分にジャンプテーブルを置く方法です。2ステップ分の時間を消費しますが、どこに配置してもジャンプできます。また、サブルーチンが肥大化して256ステップを超えても前半部分にCALL先を配置することは可能です。
 PICマイコンの開発当初はアドレスが少なかったことと、すべての命令を1ステップにしたことによりこのような状態が発生したと思います。現在ではほとんどの品種でプログラムカウンタが増設(PCL+PCH+ページ)されているので使い易くなったと思います。
2.スタック
 割り込みの無いベースラインではスタックは2段しかありません。しかし1ページ以内であれば、PCLを保存することによってGOTO命令でCALLを実現することが可能です。まずMOVLWでオーバーヘッド分をアキュムレータに入れてADDWFでPCLを加えてMOVWFでスタックするレジスターにPUSHします。次にジャンプ先アドレスをMOVWFでPLCを書き換えジャンプします。そして戻る時はRETLWではなく、スタックをPCLに書き込みます。
 もちろん別のページに行くことも可能です、この時はPCLの書き換えの前にページビットを書き換えておく必要があります。戻るときも同じです。
3.TMR0の16ビット的利用法
 オーバーヘッドが生じないほど低速なパルスを計測する場合に限りこの手が使えます。プリスケラーをTMR0とWDTで切替ますのでWDTは無しで使用します。
まずレジスターを1ビット用意します。これをフラグにしてまず計測値に近い値になるようにプリスケラーとTMR0を設定します。TMR0のアップをポーリングで検知したらプリスケラーをWDTに変更、TMR0を残数に設定、フラグをONしてつぎのポーリング検知でTMR0のアップを検出したら計測完了とします。例えば商用電源をクロック源にした場合20分程度のタイマーが作れます。フラグがOFFの場合はアップするまで相当時間がありますが、残数計測は時間が速いのでポーリング間隔はTMR0クロック以内に収めた方が無難でしょう。
4.1つのIOで入出力
 少ないPIN数で如何に自分の考えを具現化するかが、電子工作の醍醐味だと思います。そこで単純な処理の場合(LEDの点灯+切替用押釦スイッチ)の様な場合、同一ポートに割付できないか考えてみました。まず負荷(LED)は+側にレイアウト、当然電流制限抵抗も。そして―側にスイッチとダイオードを接続、スイッチはグランドへダイオードの向きははPICのポートへ、PICへ電流を吸い込むように接続します。ダイオードはPICのポートをトーテンポールからオープンドレインにする為に入れるので元々オープンドレインのポートは必要ありません。これによりPICの出力がHIの時に押釦が押されてもPICが壊れる心配はありません。
プログラム的にはPORT出力をLOW、TRISを入力状態で待ちます、(出力しててもべつにいいですが説明の便宜上)押釦が押されるとLEDが点灯、PICのポートはLOWになります。数m秒待って(チャタリング防止)ポートがHIになったらTRISで出力に切替ます。この時PORTはLOWです。見た目にはLEDは点灯を続けます。次に押釦が押されたかどうかは定期的にTRISを切替て確認します。もしPORTがLOWであれば押釦が押されているので、そのまま押釦が離れるのを待ち離れたらフラグをOFFにします。PORTの出力はLOWのままでTRISで入力にすることによりLEDをOFFにします。
もし押釦が押されていなければTRISを出力に戻します。入力チェックには数μ秒しかかからないので見た目には点灯を続けます。