楽々PIC

水田除草と言うブログを書いていますが、PIC関連の記事が意外に人気で驚いています。 PICを使った電子工作に興味を持つ方が多いことを知って、一緒にPICを学ぶブログを作りたいと思いました。 「楽々PIC」は教材と言うよりも少し実用性?のある楽しい道具を作りながら学ぶブログを目指します。

割り込み

ディジタル温度センサー4

ディジタル温度センサー3」で紹介した割り込み処理からフックで実行されるプログラムの内、DS18B20+ にコマンドを送信(書き込み)する部分と、温度データを読み出している部分のアセンブラソースを紹介します。 クロック周波数8MHzでの実施例です。 実行サイクル数やNOPコマンドで時間調整している為、クロック周波数が異なる場合には調整が必要です。

下図がコマンドを送信(書き込み)する部分です。

write2

先の書き込みスロットを終了する為に 1.5usec 間 1-Wire-バスを解放した後で、書き込みスロットの先頭で 1.5usec 間バスに Low を出力します。 その後送信データに従ってバスに High または Low を出力して割り込み処理を抜けます。 最初の 1.5usec は次の割り込みまでのタイマー設定を行う間に確保されます。 2つ目の 1.5usec は送信データのシフトとNOP命令で確保しています。

下図は、温度データを読み出している部分のアセンブラソースです。

read2

先のスロットを終了させる為に 1.5usec 間 1-Wire バスを解放した後で、1.5usec 間バスに Low を出力し、さらに 9.5usec 経過した時点でバスを読み出して割り込み処理を抜けます。 クロック周波数が8MHzでは10usec程度の待ち時間は割り込みを抜けずにNOPで処理する方が安定するし、他の(低位)割り込み処理にも不具合は予想されないと思います。

関連記事のインデックスは右記事の末尾にあります。 → ディジタル温度センサー


楽々PIC」は楽しい道具を作りながら学ぶブログを目指します。





ディジタル温度センサー3

DS18B20+ で温度測定をする為に「ディジタル温度センサー2」で紹介したように1秒間を超える手続き(ポート入出力)が必要です。 この間も温度制御や赤外線リモコン受信を並行して進める為に、可能な限り割り込み処理で必要な手続きを進める必要があります。

1-Wire バス・プロトコルは少々面倒な部分がありますが、今回の目的を実現する分には予め決まっているタイミングで以下4種類の処理を組み合わせて淡々と進めるだけで、複雑な分岐処理はありません。

1. ポートに Low を出力
2. ポートに High を出力
3. ポートを入力ポートに設定
4. ポートの値をサンプリング

RRP1320-1-04-2 の温度センサーを DS18B20 に置き換える為、他の処理(例: 赤外線リモコン受信)よりもシビアなタイミング管理が必要な 1-Wire バス・プロトコル用に、高位割り込みに設定した TIMER3 割り込みを使うことにしました。
DS18B20 は RB0 に接続し、RB0 について先の4種類の処理を行います。 クロックは内臓 8MHz のままです。

タイミングがシビアなので、割り込み発生の都度分岐するのではなくて、割り込み直後に前述4種類の内(予め決められた)いずれか一つの処理を行い、次のタイミング(割り込み)に備えて TIMER3 を設定し、次回割り込み時に実行するプログラムを指定(予約)することにしました。

TIMER3 割り込みの都度指定されたプログラムを実行する為に、フック( HOOK )を使っています。 データ・メモリーとプログラム・メモリーが分かれている PIC の場合はフックと呼べないかも知れませんが、TIMER3 割り込み処理の先頭で所定のデータ・メモリー( 3byte )を参照して指定(予約)されたアドレスにジャンプします。

下図は、TIMER3 割り込みを処理する高位割り込みプログラムのアセンブラ・ソースです。

inthigh-0

割り込みフラグをクリアして直ぐに、データ・メモリーに指定(予約)されたアドレスにジャンプしています。(10~13行目)

下図はジャンプ先の一例で、リセットパルスの後でデバイスの存在パルスをサンプリングするプログラムです。 ディジタル温度センサー2 に示したタイミング図の内、リセット・パルスの丸囲みSに相当するタイミングで実行されます。

inthigh-2

44行目でサンプリングを行い、結果を dsstf < 1 > に反映させるとすぐに次の割り込みタイミングを規定する為に(予め準備された) TIMER3 を設定しています。(46,47行目)

続いて、次の割り込み時に次々回の割り込みタイミングを規定する TIMER3 の設定値を準備し、次回割り込み時のフックアドレスを指定(予約)します。 続く書き込み(送信)処理に必要なワークの準備を済ませて、最初の図の15行目にジャンプしています。
67行目に RETFIE  FAST と書いても良いのですが、フックを使うと解り難いソースになる為、少しでも読みやすくする工夫のつもりです。

関連記事のインデックスは右記事の末尾にあります。 → ディジタル温度センサー


楽々PIC」は楽しい道具を作りながら学ぶブログを目指します。




デバッグ難航

 RRP1320-3-01-1 はデバッグに手間取りました。 赤外線リモコンで点灯パターンを切り替える際に、作った覚えの無い点灯パターンで動き出します。 しかも稀に発生する現象でてこずりましたが、安定するようになりました。 写真のように拡散用キャップの手持ちが無いので、入荷待ちの間に点灯パターンを増やして置きたいと思います。

DSC00207


今回は高位割り込み中のテーブルジャンプに掛け算を使うのですが PRODH , PRODL の退避・復旧を行わなかった為、メインレベルの掛け算に(稀に)不具合を発生させていたことが主原のバグでした。 下図アセンブラ・ソースのようにバックアップを取ることで安定しました。

テーブルジャンプ

他にも LED を実際に点滅制御する高位割り込み( TIMER1   1msec )、点灯パターンを刻々と切り替える低位割り込み( TIMER0   50msec )、赤外線リモコン受信に応じて点灯パターンのテーブル参照情報を差し替えるメイン処理の連携に不具合の無いように工夫しています。

メイン処理によるテーブル参照情報差し替えでは複数のデータを上書きしますが、途中で低位割り込みが入るとデータ不整合が予想される為、差し替え作業中を示すフラグを作りました。 低位割り込み処理がこのフラグを検出すると次回割り込み(50msec後)まで予定処理を延期して不具合を回避します。


楽々PIC」は楽しい道具を作りながら学ぶブログを目指します。




焦電センサー

 RRP1320-2-01 に焦電センサー(焦電型赤外線センサーユニット) SE-10 を使っています。 センサー感度 約2m、検知角度 約 120 度 で、人が動くと出力がLowになります。 ただし、感知保持タイマー回路が無く、常に人が居ても出力が散発的に High になります。

モノマルチ

人を検出して「いらっしゃいませ」と発声させたいのですが、このままでは頻繁に「いらっしゃいませ」を繰り返してしまいます。 そこでソフトウェアで感知保持タイマー機能を実現します。

上図のように時間 t のタイマー(リトリガラブル・モノマルチバイブレータの様な働き)を使って、感知保持を行います。 焦電センサー出力が Low の時にタイマーを初期値に戻し、TIMER0 で 0 になるまで DEC (-1)します。加工後の出力はタイマーが 0 以外の間 Low を保ち、0になったら High に戻します。

サンプリングの結果、焦電センサー出力が Low の時には毎回タイマーを初期値(10秒)に戻す様子を破線で示しています。 代表的なタイミングだけですが、上図のように次々と初期値に戻される為、散発的な High 出力(斜線部)が無くなります。 一方で、最後に焦電センサー出力が Low であった時刻から設定時間(10秒)後に加工後の出力が High に戻る遅延が発生しますが、人を検出して「いらっしゃいませ」と発声させる用途であれば困らないと思います。

下図は実施例(アセンブラ・ソース)です。

感知保持タイマー

加工出力 inpds<bit2> は直前に 0 クリアされています。 RB0 が 0 (アクティブ)であれば感知保持タイマーを初期化します。 感知保持タイマーが 0 になったら加工出力を 1 にセットします。

感知保持タイマーデクリメント

なお、感知保持タイマーは TIMER0 割り込みの中で、上図のように条件付きデクリメント(値0でクリップ)されます。


楽々PIC」は楽しい道具を作りながら学ぶブログを目指します。




EEPROM 読み書き

 「EEPROM 初期設定」で紹介し通り、内臓 EEPROMに初期値を書き込む時にはアセンブラの疑似命令 DE を使うのが便利です。 一方で、処理中の定数をEEPROMに保存して、再起動時に活用するような場合は EEPROM にを読み書きするプログラムが必要になります。

下図はプログラム・メモリー上にある 20byte のデータ列を EEPROM に書き込んでいます。 リセット直後の初期化処理用に作った為、1byte 書き込みの都度完了を待つ間(数msec)は他に何もせずにループしています。 リアルタイム処理を行いながら書き込む場合は割り込みを使う必要がありますが、ここでは動作確認済みの読み書き手続きを説明することを目的にします。 <PICデバイス=18F1320>

EEPROM に書き込む手順は以下の通りです
 (1) EEADR にアドレスを書き込む
 (2) EEDATA にデータを書き込む
 (3) アクセス先として EEPROM を選択 ( BCF  EECON1 , EEPGD )
 (4) 書き込み許可指示 ( BSF  EECON1 , WREN )
 (5) 書き込みシーケンス1として EECON2 に値 055H を書き込む
 (6) 書き込みシーケンス2として EEOCN2 に値 0AAH を書き込む
 (7) 書き込み指示 ( BSF  EECON1 , WR )
 (8) 書き込み完了待ち EECON1 <WR> が 0 になるまで待つ
    (あるいは完了割り込み処理を作成)
 (9) 書き込み禁止指示 ( BCF  EECON1 , WREN )

連続して 2byte 以上を書き込む場合は、1byte 目に(3)~(4)を実行して 2byte 目では省略しても問題ないようです。 念の為、下図の通り EEPROM アクセスの最初に BCF  EECON1 , CFGS も実行し、誤ってコンフィグレーションビットにアクセスしないようにしています。

EEPROM書き込み


下図は、正しく書き込めたか確かめるべリファイ処理です。

EEPROM を読み出す処理は以下の通りです。
 (1) EEADR にアドレスを書き込む
 (2) アクセス先として EEPROM を選択 ( BCF  EECON1 , EEPGD )
 (3) 書き込み指示 ( BSF  EECON1 , RD )
 (4) EEDATA からデータを読み出す

読み出し時には完了待ちや割り込み処理は不要で、(3)の後すぐに読み出せます。
連続して 2byte 以上の読み出しを行う場合の(2)は、前述書き込み時と同様の扱いです。

EEPROMべリファイ

以上のようにプログラムで書き込んだ内臓 EEPROM の内容は MPLAB の EEPROM ウィンドウに反映されない点に注意が必要です。 ブレークポイントを設定し、プログラムを止めて EEDATA の内容を見るなどデバックに手間がかかります。 最終的には EEPROM から読み出した値をデータ・メモリーに書き出して確認しました。

今回は、上図のプログラムはいずれも不採用にしましたが、近いうちに赤外線リモコンを使ってプログラム定数を変更する場面で EEPROM の読み書きが必要になると思います。 その時には EEPROM 割り込みを使ったプログラムを紹介したいと思います。


楽々PIC」は楽しい道具を作りながら学ぶブログを目指します。



ダウンロードコーナー
記事検索
アンケートに御協力下さい


アーカイブ
楽々PIC 宛てBlogMail


--- ご了承下さい ---

注意して記事を書いていますが、記事及びリンク先の情報による不利益について、一切責任を負い(負え)ません。
QRコード
QRコード
アクセスカウンター

    Atsuhiro Imai

    バナーを作成


    プロフィール

    jyosou_robot

    • ライブドアブログ