楽々PIC

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

18F一般

EEPROM 初期設定

 RRP1320-1-02 では予め内臓 EEPROM に記録した赤外線リモコンの受信コードを元に、押されたボタンを特定して所定のサブルーチンを CALL します。 EEPROM に初期値を書き込む方法について説明してみます。  <PICデバイス=18F1320>

EEPROM に初期設定を書き込む際には、下図のようにアセンブラの DE 疑似命令を使います。 プログラム・メモリーにテーブルを準備する時に使う DB 疑似命令と同様に使えるようです。

EEPROM_DE

ORG 疑似命令で先頭を指定して、DE 疑似命令を並べます。 PIC18F シリーズでは 0F00000H ~ 0F000FFH の 256byte を指定します。 上図のように指定した結果は、EEPROM ウィンドウでも確認できます。

PICkit3 をプログラマーに設定して PIC に書き込む際には、Programmer → Settings で表示される PICkit3 Settings ウィンドウの Program Memory タグにある Memories EEPROM にチェックが入っていることを確認する必要があります。

Programmer_Settings


DE 疑似命令を使うと下図の通り、自動的にチェックが入るようです。

Program_Memory

初めは DE 疑似命令を知らずに、プログラム・メモリーに DB 疑似命令でテーブルを準備して、自前のプログラムで EEPROM に転送していたのですが、一般的でない上に EEPROM ウィンドウに反映されない為、DE 疑似命令による初期設定に変更しました。

EEPROM に転送するプログラムは書き込みとべリファイの為の読み出しを行うものですが、動作中にEEPROMを書き換える時に応用できると思いますので、別の記事「EEPROM 読み書き」で動作確認済みソースを紹介しています。


赤外線リモコン受信の関連記事インデックスはこちら → 「赤外線リモコン受信


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


13bit 加算・減算

 「加算・減算」と言う記事で、1byteデータの加算を例示していますが、今回は 13bit 以下のデータ同士の加算と減算です。 コーディング中の赤外線リモコン受信プログラムの一部アセンブラ・ソースで説明します。 <PICデバイス=18F1320>

下図のコメントに 16bit とありますが、197~202行目の加算処理ではオーバーフローの可能性があることに注意が必要です。 赤外線リモコン受信プログラムの中で下図が扱うデータは 13bit 長以下のためこのまま使います。 また181~186行目で入力値の大小比較に基づく分岐を行って、減算時結果が負にならない設計です。 デバックの結果、下図の大小比較には不充分な点があります。 加算・減算部のみ参考にして下さい。 (08/20日追記)

13bits_add_sub

プログラムは、入力値( shiftwh , shifutwl , irtoldh , irtoldl , irtim0h , irtim0l )を破壊することなく出力先( irtdth , irtdtl )に演算結果を記録します。
なお、前述ラベル名の末尾 h , l はそれぞれ上位、下位を示します。

加算・減算共に下位から演算を初め、下位同士の演算ではキャリーまたはボローを含まない命令を使います。 続く上位同士の演算ではキャリーまたはボローを演算に含めます。 16bit 長を超える値同士の演算も同様に、最下位の演算だけはキャリーまたはボローを含まず、他はキャリーまたはボローを含む命令を使います。


一連の記事のインデックスは 「とにかくビルド!」の末尾をご覧下さい。


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





ビットシフト

 赤外線リモコンの受信に挑戦中です。 Webでの調査と予め入手していたセンサの波形確認を終えてコーディングに取り掛かったところです。 このブログで製作する道具の一部に使いたいと考えていますから、赤外線リモコン用に専用のタイマーを割り付けるのではなく、キー走査やイベントタイマー用に使っているTIMER0を読み出して使おうと考えています。 うまく出来たら紹介します。

コーディング中にビットシフト命令を使う場面があったので紹介します。
PIC18Fシリーズのビットシフト命令は以下の4つです。

         RLCF           f , d , a     ;  f の値を左シフトした値 を W または f に記録 キャリー使用
         RLNCF        f , d , a     ;  f の値を左シフトした値 を W または f に記録 ループ
         RRCF           f , d , a     ;  f の値を右シフトした値 を W または f に記録 キャリー使用
         RRNCF        f , d , a     ;  f の値を右シフトした値 を W または f に記録 ループ

「キャリー使用」と書いたものは以下( RLCF )のようにキャリーフラグを使ってシフトします。
 実行前C→bit0  bit0→bit1  bit1→bit2  bit2→bit3  bit3→bit4
                                                bit4→bit5  bit5→bit6  bit6→bit7 bit7→実行後C

「ループ」と書いたものは以下( RLNCF )のようにループ状にシフトします。
                             bit0→bit1  bit1→bit2  bit2→bit3  bit3→bit4
                                                bit4→bit5  bit5→bit6  bit6→bit7 bit7→bit0


下図は「キャリー使用」のアセンブラ・ソースです。 <PICデバイス=18F1320> 32bit( 4byte )のデータを左シフトしています。 最後に実行前キャリーの値によって不定になる 32bit 中の最下位ビットを0クリアしています。 2byte 以上のデータをシフトする時には「キャリー使用」の命令を使います。

shift_l


今度も「キャリー使用」ですが右シフトです。 16bit( 2byte )のデータを右に3回シフトしています。 最後に上位データーの bit5bit7 を0クリアしています。 「キャリー使用」のビットシフトは byte の手順(上位と下位)も重要です。

shift_r3

「ループ」と書いたシフト命令はステッピングモーターの制御信号など、1byteの同じ値をグルグル回し続ける用途に使います。


一連の記事のインデックスは 「とにかくビルド!」の末尾をご覧下さい。


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



OR と AND

 記事「加算と減算」で、論理演算については実際に使う場面で紹介することにしていましたが、「LCDに自動転送2」と言う記事で OR と AND を使っています。 各々の真理値表は下図の通りです。

OR_AND

OR と AND を演算を行う18Fシリーズの命令は以下のものがあります。


         IORWF           f , d , a     ; データ・メモリー f の値と W の値の OR を W または f に記録
         IORLW           k               ; 値 k と W の値の OR を W または f に記録
         ANDWF         f , d , a     ; データ・メモリー f の値と W の値のANDを W または f に記録
         ANDLW         k               ; 値 k と W の値のANDを W または f に記録


下図は「LCDに自動転送2」に紹介したアセンブラ・ソースで、84行目に IORWF 命令を使っています。  <PICデバイス=18F1320>
ここで W には上位 4bit が0の値が入っていて、LATA(ポートA)の出力値と W の値のORをLATA(ポートA)に出力する目的で使っています。 LATAの下位 4bit は直前の80~83行目で0クリアしていますから、LATAの上位 4bit に影響を与えることなく、W の下位 4bit をLATA(ポートA)に出力しています。

lcd_subsub


同じ記事にANDも登場します。 ここでは 0FH と W の値をANDすることで、Wの値の上位 4bit を0クリアしています。 W の値の下位 4bit に変化はありません。

lcd_int

このように 1byte データの一部を構成する複数の bit を他の bit に影響を与えずにまとめて変化させる場面で OR と AND を使うことがあります。

なお、上図の例で SWAPF 命令が使われていますが、この命令はデータメモリー f の値の上位 4bit と下位 4bit を入れ替えた値を f または W に記録する命令です。 ここでは 1byte 長の値を上位・下位 4bit に分けて転送する目的で使っています。 

一連の記事のインデックスは 「とにかくビルド!」の末尾をご覧下さい。


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



ゼロフラグ と キャリーフラグ

 演算結果によって変化するステータスフラグの内、ゼロフラグとキャリーフラグについて説明します。 ゼロフラグはループ処理の終了判定と言った場面で頻繁に使いますし、キャリーフラグは8bit長を超える数値演算で重要な役割を果たします。 ニーモニックによってステータスフラグが変化するものと、そうでないものがありますから命令一覧表などで確認して使います。 期待した変化が得られない命令の後でステータスフラグによる分岐命令を書くと、不安定な動作を伴うバグとなって原因解明に苦労する場合があります。

ステータスフラグはSFRの一つ、STATUS の値です。 SFRもデータ・メモリーと同様に読み書きできますが、通常ステータスフラグを直接読んだり書き換えることは行わず、ステータスフラグの内容によって分岐する命令( BC , BNC , BNZ , BZ など)や、キャリーフラグ(またはボロー)の値を演算に含める命令( ADDWFC , SUBFWB , SUBWFB など)を使うことで活用されます。 (PICにボローフラグは無く、減算命令後のキャリーフラグの反転を使います。)


<<< ゼロフラグ >>>

間接アドレッシング」で例示したソースリスト(下図)の31行目に BZ 命令を使っています。 30行目の MOVF で W に読み出した値によってゼロフラグが変化し、31行目でゼロフラグの値が1なら hotz に分岐します。
MOVF 命令でゼロフラグが変化することを確かめて使っています。

Block3



<<< キャリーフラグ >>>

キャリーフラグは8Bit長からの桁あふれ(オーバーフロー)を示すステータスフラグです。 下図の筆算で各桁毎に「1繰り上がる」場面でキャリーフラグの値が1になります。 10進数の筆算では一桁が0~9の値ですが、8bit長では0~255の値をカバーします。

carry

キャリーフラグは「掛け算(乗算)」の例、参照アドレス計算の中で ADDWFC 命令を使って活用しています。

他のステータスフラグについては、必要の応じて別の記事で紹介します。


一連の記事のインデックスは 「とにかくビルド!」の末尾をご覧下さい。


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



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


アーカイブ
楽々PIC 宛てBlogMail


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

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

    Atsuhiro Imai

    バナーを作成


    プロフィール

    jyosou_robot

    • ライブドアブログ