2001/12/12 【ソフトウエア編TOPに戻る】
前回は、PIC16F84Aを使ったPIOのプログラム例をご紹介しました。今回は、同じことをPIC16F873を使ってやってみます。
PIC16F873はPIC16F84Aに比べると、A/D変換、タイマー機能、通信機能、PIOポート数など、あらゆる面で多機能になっています。
PICにはいくつかのシリーズがあり、それぞれに多くのファミリーがラインナップされていますが、基本的なアーキテクチャは共通化されていて、プログラムの移植性も非常に高いものです。しかし、デバイスの種類によって付いている機能や付いていない機能があり、それらは一種のクセを生みます。つまり、あるプログラムを違う種類のPICで使おうする時には、そのクセをつかみ、ちょっとだけプログラムを手直ししてあげたりする必要があります。
今回は、PIC16F84A用に作ったプログラムpiotes1A.asmを、PIC16F873用に作り直してみて、その両者の違いを実際にみてみましょう。
311−1.PIC16F873用のPIO入出力プログラムpiotes1B.asm
さて、今回のプログラムも、前回ご紹介したPIC16F84Aのプログラムと基本的には同じです。なので、いきなり実際のプログラムをご紹介してしまいます。しかしちょっとだけ違う点があります。ここでは、そのPIC16F84AとPIC16F873のプログラムの違いだけを見てみましょう。
ここをクリックすると以下のソースコードをダウンロードできます。piotes1B.asm
|
;********************************************************************** |
311−2.PIOテストプログラムpiotes1B.asmの説明
基本的にはPIC16F84A用のプログラムと一緒ですが、以下の点で違いがあります。
■list文のプロセッサ指定変更
list p=16F873
これは大体予想できる変更点です。PIC16F84Aの時には「16F84A」と書いてあった部分を「16F873」に書き換えて、プロセッサを指定し直しています。
■インクルードファイルの指定変更
#include <p16F873.inc>
これも予想できますね。PIC16F873用のレジスタ設定のされたインクルードファイルに指定し直します。ただし、MPLABがインストールされているフォルダに、このファイルがあることを確認しておく必要はあります。
■コンフィグレーションビットの設定追加
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF
これはちょっと予想できませんでした。コンフィグレーションビットの設定に、「_LVP_OFF」という設定を追加しています。
ところで、PIC16F873のコンフィグレーションビットには、以下の項目があります。その中で、ビット名の部分を黄色で表示しているビットが、16F84Aにはなかったものです。
PIC16F873のコンフィグレーションビット
| ビット名 | 選択肢 | 説 明 |
| FOSC | RC/HS/XT/LP | PICに使用している発振回路を指定する。 |
| WDTE | ENABLE/DISABLE | ウォッチドックタイマを利用するかしないかを指定する。 |
| PWRTE | DISABLE/ENABLE | 電源投入直後の72mS期間のリセット動作をするかしないかを指定する。 |
| BODEN | ENABLE/DISABLE | ブラウンアウトリセット(電源電圧低下によるリセット)をするかしないかを設定する。 |
| LVP | RB3:PGM/RB3:GPIO | 低電圧(5V)プログラミングの有効/無効を設定する。有効だとRB3端子はプログラミング専用になる。 |
| CPD | DISABLE/ENABLE | 内部EEPROMデータメモリのコードプロテクトをするかしないかを設定する。 |
| WRT | ENABLE/DISABLE | ユーザープログラムがEECONレジスタを使用してFLASHプログラムメモリへの書き込みをするかしないかを設定する。 |
| DEBUG | DISABLE/ENABLE | インサーキットデバッグモードの有効/無効を設定する。有効だとRB6,RB7端子はデバッグ専用になる。 |
| CP | DISABLE/0800H-0FFFH/0F00H-0FFFH/ALL | コードプロテクトをするかしないかを指定する。 |
今回は、& _LVP_OFF というのを追加しました。これは、RB3ビット(PORTBの3ビット目)を低電圧プロブラミング用の特殊用途として使用せず、PIOの汎用端子として使用するという設定です。このLVP設定ビットは、初期設定で特殊用途に割り当てられてしまうため、ここで設定を変更しています。
この設定を行なわないと、PORTBの3ビット目は常に1の状態となります。つまり、3ビット目のLEDは常に点灯状態になり、プログラム上からの制御が行なえません。汎用PIOとして利用する場合には、必ず & _LVP_OFF を追記してください。
その他のコンフィグレーションビットは、わざわざ設定を追記していません。それは、初期状態のままで正常に動作するためです。ただし本当は明示的に設定を行なうべきかもしれません。ただ手抜きをしただけとも言えます...
■A/Dコンバータ用レジスタの設定追加
MOVLW
06H
;Wレジスタに06Hをセット
MOVWF
ADCON1 ;ADCON1に06Hをセット PORTA全てデジタル
ん?? 今回のプログラムはスイッチ入力をLED表示させるだけで、A/D変換なんて使ってないのに、何でそんなことするの???
と怒られそうですが、どうしてもこれが必要なのです。
A/D変換機能の設定を行なうレジスタにはADCON0とADCON1の2種類があります。
ADCON0は変換クロックの選択やアナログ入力チャンネルの選択、あとはA/D変換動作の状態を取得するなど、実際のA/D変換時に活躍するレジスタです。
そして、ADCON1はアナログ入力が可能な端子を、本当にアナログ入力として使うのか、デジタル入出力用として使うのかを設定します。また、アナログの基準電圧をどこから取得するかといった設定も行ないます。今回の設定に必要なのは、このADCON1のほうです。
ADCON1には、以下の機能があります。
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| ADFM | - | - | - | PCFG3 | PDFG2 | PCFG1 | PCFG0 |
ADFMビットについては、実際のA/D変換機能をご紹介するときに説明します。ここではPCFG0〜3ビットが端子の用途を決定する要因となり、以下のようにして決まることを見て下さい。
| PCFG3,2,1,0 | AN4/RA5 | AN3/RA3 | AN2/RA2 | AN1/RA1 | AN0/RA0 | Vref+ | Vref- |
| 0 0 0 0 | A | A | A | A | A | VDD | VSS |
| 0 0 0 1 | A | Vref+ | A | A | A | RA3 | VSS |
| 0 0 1 0 | A | A | A | A | A | VDD | VSS |
| 0 0 1 1 | A | Vref+ | A | A | A | RA3 | VSS |
| 0 1 0 0 | D | A | D | A | A | VDD | VSS |
| 0 1 0 1 | D | Vref+ | D | A | A | RA3 | VSS |
| 0 1 1 x | D | D | D | D | D | VDD | VSS |
| 1 0 0 0 | A | Vref+ | Vref- | A | A | RA3 | RA2 |
| 1 0 0 1 | A | A | A | A | A | VDD | VSS |
| 1 0 1 0 | A | Vref+ | A | A | A | RA3 | VSS |
| 1 0 1 1 | A | Vref+ | Vref- | A | A | RA3 | RA2 |
| 1 1 0 0 | A | Vref+ | Vref- | A | A | RA3 | RA2 |
| 1 1 0 1 | D | Vref+ | Vref- | A | A | RA3 | RA2 |
| 1 1 1 0 | D | D | D | D | A | VDD | VSS |
| 1 1 1 1 | D | Vref+ | Vref- | D | A | RA3 | RA2 |
A:アナログ入力端子として機能する。
D:デジタル入出力端子として機能する。
Vref+:A/D変換のとき、アナログの基準電圧のプラス端子として機能する。
Vref-:A/D変換のとき、アナログの基準電圧のマイナス端子として機能する。
VDD:PICのプラス側電源端子
VSS:PICのマイナス側電源端子(GND)
ここで何もしないと、ADCON1レジスタは 0 0 0 0の値をとります。つまり、PORTAの0,1,2,3,5の各ビットは、全てアナログ入力用の端子の設定になっています。PICのデータシートには、「アナログ入力として構成されているピンをリードすると、0(Lowレベル)とリードされます」とあります。つまり、アナログ入力に設定されている端子をPIOのつもりでデータを読むと、必ず0(ゼロ)として読まれるということです。これでは正常なデジタルデータの入力は出来ません。
そこで、
MOVLW
06H
MOVWF
ADCON1
によって、ADCON1レジスタに06Hのデータを書き込んでいます。06Hつまり 下位4ビットは0110ですので、上の表の青色の設定によって全てデジタル入出力として使えるということになります。
なんで初期設定でデジタル入出力じゃないの?なんて言わないで下さい。そういうものなのだから仕方ありません。そこがクセということになるのでしょう。
■あとは変更点なし。
あとはPIC16F84Aと同じプログラムです。ただし、今回は使用していませんが、データの一時保管場所である汎用レジスタなどを使おうという場合は、その開始アドレスが異なるため注意が必要だったりもします。
311−3.実験風景
以下が実験風景の写真です。
![]() |
左側がPIC16F873を載せた実験基板で、右がテスト用の簡易I/O基板です。 右側の基板の下の方で、LEDが6ビット分点灯しているのが分かりますか?その部分が同じ基板についているディップスイッチの状態で点灯/消灯します。PIC16F84Aの時は5ビット分まででしたが、PIC16F873はPORTAが6ビット分まで対応しているため、こうなります。
|
今回はPICの機種ごとに持つ機能の違いに起因するクセをつかんで、プログラムを移植する例をご紹介しました。動作がなぜか変で、プログラムをいくら見直しても原因がつかめない!といったことが起きた場合には、コンフィグレーションビットや、関連しそうなレジスタの設定を見直してみて下さい。そこに原因が隠れているかもしれません。