楽々PIC

水田除草と言うブログを書いていますが、PIC関連の記事が意外に人気で驚いています。 PICを使った電子工作に興味を持つ方が多いことを知って、一緒にPICを学ぶブログを作りたいと思いました。 「楽々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」は楽しい道具を作りながら学ぶブログを目指します。




18F: BCD

BCD をキーワードに検索して来てくれる方がいらっしゃいます。 BCD ( Binary-coded decimal )は二進化十進数と呼ばれ、10進数を2進数( 4bit )で表現します。 何と言っても慣れ親しんだ10進数を扱う為に必須の手法です。 楽々PICでもLCD表示は勿論、時間や温度の設定などは人に親しみ易い10進数を扱うために頻繁に使っています。

下図は2進数を指折り数える方法で、折り曲げた指が 1 を広げた指が 0 を示し、親指( bit0 )~薬指( bit3 )の順に使います。 4bit で表現できる0~15(16通り)を数え、最後に小指だけ折り曲げた絵が bit4 への桁上がりです。 5本指( 5bit )で表現できるのは32通りですが、指がつりそうな絵が出てきます。 ちなみに私は下図16番ですら左手の助けを要します。(笑)

手4bit

BCDは 4bit で表現できる16通りの中から四角く囲った10通りだけを使います。 残り6通りの情報が無駄になるのですが、親しみ易さには代えられません。

8bit 16進 000H~0FFH は256通りの表現が出来ますが、この内10通りだけを使って 000H~009H と表現するのが一桁BCD、上下各 4bit (16通り)の内10通りだけを使って 000H~009H~010H~099H と表現するのが二桁BCDです。 一桁BCDは10/256と言う効率の悪さが気になりますが、ASCII変換や計算をする時に扱い易い点が特徴です。

言葉であれこれ説明するより、幾つかの例をアセンブラ・ソースで示します。 <PICデバイス=18F1320>
2桁BCDを入力値に、次の処理をしています。

 (1)2桁BCDを1桁BCD(2byte)に分離 (逆変換は省略)
 (2)1桁BCDを ASCII Code に変換 (逆変換は省略)
 (3)1桁BCDを2進数に変換
 (4)100未満の2進数を1桁BCD(2byte)に変換

4bit を切り出すために AND でマスクしたり、上位 4bit と下位を入れ替える SWAPF (チョットめずらしい命令)を使っています。 私は常にBCD→バイナリーと一方向に変換するので、バイナリーからのBCD変換は初めてです。 DAW と言う命令が使えるのかと期待してしまいましたが2桁BCDからの桁溢れを調べる命令のようです。(もう少し調べてみます)

BCD


下図は、上図の実行結果です。

BCD1


18F ニーモニックと小技のインデックスはこちら → 18F: テーブル・ジャンプ 


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



18F: テーブル・ジャンプ

「テーブル・ジャンプ」 や 「ジャンプ・テーブル」と言った検索をして来てくれる方がいらっしゃいます。

RRP1320-1-02-1 , RRP1320-1-03-1 , RRP1320-1-04-1 では、赤外線リモコンの受信コードに応じて16個、登録外コード受信時に1個の合計17個のサブルーチンをコールします。 中間コードを比較しながら分岐命令を連ねて受信コード毎の分岐を実現していましたが、ジャンプ・テーブルを使った方法を試してみました。 <PICデバイス=18F1320> 今後アップロードするプロジェクトから適用します。

PIC18F のテーブル・ジャンプは PCLATU , PCLATH にジャンプ先のアドレス上位、中位を準備して、PCL に下位を書くことで実現します。 下図はテーブル・ジャンプを使っているアセンブラ・ソースで、ircchk5 に実行を移す時点で ircode に 1~16(10進数) の値が入っています。

初めに PCLATU , PCLATH , ircd3(私設ワーク) にジャンプ・テーブルの先頭アドレス( ircchk51 )を準備して、( ircode - 1 )を2倍した値を加算することで、目的のジャンプ・アドレスを完成させます。

Jump_Table

最後に PCL に下位アドレス( ircd3 )を書き込んでジャンプ・テーブル内にジャンプします。 初め PCL への転送に MOVFF を使いましたが、アセンブラーがエラーを返して MOVFF は使えないと教えてくれました。 MOVWF なら問題なく BUILD SUCCEEDED です。

連番に基づく分岐処理の他、ジャンプ先のアドレスをデータ・メモリーに書いてジャンプ先を制御したいと言った時に使います。 PICではデータ・メモリーにジャンプ命令を書いて実行させることは出来ませんが、フック( HOOK )同様の動作が可能です。


以下は 18F ニーモニックと小技のインデックスにします。
以前の関連記事インデックスは とにかくビルド! です。


18F: DECF とボロー 
 減算タイマーの処理で DECF を使っていますが、2byte 以上のデータを扱うとボロー(桁下がり)の処理が必須にです。 引き算 SUBWF では上位 byte の引き算に SUBFWB を使ってボロー(Cの反転)を引き算しますが、DECF でも同様にキャリーフラグが動作するのか調べてみました。

18F: BCD 
 BCD ( Binary-coded decimal )は二進化十進数と呼ばれ、10進数を2進数( 4bit )で表現します。 何と言っても慣れ親しんだ10進数を扱う為に必須の手法です。


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



18F: DECF とボロー

RRP1320-1-03 は減算タイマーの処理で DECF を使っていますが、2byte 以上のデータを扱うとボロー(桁下がり)の処理が必須にです。 引き算 SUBWF では上位 byte の引き算に SUBFWB を使ってボロー(Cの反転)を引き算しますが、DECF でも同様にキャリーフラグが動作するのか調べてみましたが納得できる資料が見当たらないので実験で確かめることにしました。 <PICデバイス=18F1320>


下図をソースに書き足し、行番号の右隣で灰色の部分をダブルクリックして、ブレークポイントを設定します。

DECF_Break


Run して、ブレークポイントで止まった所で、下図のように Watch ウィンドウで DECF 後の値と、STATUS レジスターの中を表示させます。

DECF_Break_STATUS


プログラムを書き換えて DECF 処理前の値毎に記録したのが下表です。 ついでですから、N , OV , Z , DC , C と言った全てのステータスフラグについて記録しました。

 N     演算結果が負を示すネガティブフラグ
 OV  符号付き演算のオーバーフローフラグ(7bit を超えると1)
 Z     演算結果が0を示すゼロフラグ
 DC  演算結果が下位 4bit からのオーバーフローを示すデジットキャリーフラグ
 C     演算結果が 8bit からのオーバーフローを示すキャリーフラグ

DECF_結果

やはり、DECF 直後にキャリーフラグの反転をボローとして扱えるようです。 DC の反転も上位 4bit からのボローとして機能しています。 何ごとも自分で確かめれば自信を持って先に進めます。


18F ニーモニックと小技のインデックスはこちら → 18F: テーブル・ジャンプ 


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






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


アーカイブ
楽々PIC 宛てBlogMail


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

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

    Atsuhiro Imai

    バナーを作成


    プロフィール

    jyosou_robot

    • ライブドアブログ