楽々PIC

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

18F一般

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」は楽しい道具を作りながら学ぶブログを目指します。



ポート入出力

温度制御定数と出力」の中で、下図のようにポート出力を High / Low に切り替えるアセンブラ・ソースを紹介しています。 <PICデバイス=18F1320>

温度制御出力

ポートの入出力を行う SFR には、PORTn と LATn があり上図の LATB はポートBに対応しています。 PORTn を入力(読み出し)、LATn を出力(書き込み)に使うようなので、私もそれに従っています。

PORTn と LATn の違いは以下のページが勉強になります。
 PORTレジスタとLATレジスタ
 http://homepage3.nifty.com/mitt/pic/pic1320_06.html

ポート出力は LATn に書き込み、入力は PORTn を読み出したりビットチェックを行うことで実現します。
1bit だけ書き換える場合には BSF , BCF , BTG と言ったニーモニックを使います。 複数の bit を同時に(同期して)書き換える場合は ANDWF , IORWF , XORWF が便利です。 8bit を一気に書き換える際には MOVF , MOVWF , MOVFF , CLRF , SETF 等が使えます。 ただし、8bit の中に他の割り込みプログラムで(も)書き換える bit がある場合は、割り込み処理による書き換えタイミングにより、他のプログラムの実行結果に対して意図しない悪影響を与える場合があり注意が必要です。

同様にポート入力では 1bit だけの時に BTFSC , BTFSS を使い、複数 bit を同時に(同期して)読み出す場合は 8bit 全てを読み出してから処理します。 入力時には他のプログラムに影響を与えることは無いでしょう。

ポートの入出力を行う前に下図のように各ポートについて bit 単位で入出力の設定を済ませる必要があります。

ポート定義

A/DコンバーターとUSARTの設定を先に済ませ、各ポートの入出力を設定します。 ポートとして使う bit だけでなく、A/Dコンバーター、USART、PWM、タイマー入力、外部割込みと言った用途の端子についても矛盾の無い入出力設定を行います。 (例 受信端子=入力 送信端子=出力)


楽々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」は楽しい道具を作りながら学ぶブログを目指します。






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

    • ライブドアブログ