PIC講習/入出力

概要

本章では、デジタルの入出力の基礎を解説します。
各ピンの状態はHighまたはLowのみですが、設定項目はいくつもあります。

重要語

入出力ピン

入力または出力に使えるピン

入出力ポート

8本ごとの入出力ピンのまとまり

デジタル入出力

High/Lowの2状態による入出力

必要語

レジスタ

数値を一時記憶する回路

バンク

128個分のレジスタ領域のまとまり

入出力ピン

入出力ピンは、文字通り、入力または出力の機能を持つピンです。
18ピンの16F1827には、電源供給の2本を除き、16本の入出力ピンがあります。

入出力ポート

入出力ピンは、8本ごとに入出力ポートI/O Portにまとめられています。
1827にはちょうど2つのポートがあり、ポートAとポートBという名前がついています。
また、ポートAのピンにはRA0からRA7、ポートBはRB0からRB7という名前がついています。
凹みが上に向いて見えるようにPICを置いてみましょう。
VSSとVDD以外のピンは、8ピンずつ上下に分けられます。
このとき、上側がポートAで、下側がポートBです。
RA0が17番ピン、RB0が6番ピンで、反時計回りに附番されています。

RA5

4番ピンには、RA5という名前がありますが、このピンは入力にしか使えません。
他のピンはすべて、入力と出力の両方に使えます。
RA5が入力にしか使えない理由の1つは、リセット用の回路を内蔵していることです。
もう一つは、プログラム書き込み時にこのピンから高電圧を供給することです。
入力関係に特化したピンなので、出力回路を取り付けられなかったようです。

ピン設定

PICマイコンのピンは多機能なので、使う機能の指定も複雑です。
なお、以下で新出のレジスタはすべて、基幹レジスタではない特殊レジスタです。

TRISA/TRISB

TRISA/TRISBは、ポートA/Bの各ピンについて、入出力のいずれかを指定するレジスタです。
ビット番号に対応するピンが、0で出力、1で入力になります。
これらのレジスタには、BSRと同じように、専用の書き込み命令があります。
それぞれ、TRA命令とTRB命令で、Wレジスタから値を書き込めます。
MOV命令に対する利点は、現在のバンクから変更する必要がない点です。
なお、引数はありません。
これらの命令があるので、覚えなくてもよいですが、TRISA/TRISBはバンク1にあります。
TRIS設定の例
COL.TRISA.$0C #バンク1
COL.TRISB.$0D

MBS.1
MOV.%11101000 #RA3,RA5,RA6,RA7が入力、他は出力
MOV.TRISA
MBS.0

MOV.%00001100 #RB2,RB3が入力、他は出力
TRB

ANSELA/ANSELB

ANSELA/ANSELBは、各ピンの入力がデジタルとアナログのいずれか選択するレジスタです。
0のビットに対応するピンはデジタルに、1でかつ機能を持つピンはアナログになります。
しばらくはデジタル入力しか使わないので、クリアしておきましょう。
これらのレジスタを直接設定する命令はないので、バンク3を選択しなければなりません。
ANSEL設定の例
COL.ANSELA.$0C #バンク3
COL.ANSELB.$0D

MBS.3
CLR.ANSELA     #すべてデジタル入力
CLR.ANSELB
MBS.0          #バンクは忘れないうちに戻すこと

PORTA/PORTB

PORTA/PORTBは、対応するピンの入出力の値を表すレジスタです。
これらから読み出される値は、そのときのピンの電圧に応じて、0もしくは1になります。
対応するピンが出力に設定されていても同じように動作します。
これらのレジスタに値を書き込むと、出力電圧のLow/Highを選択できます。
対応するピンが入力に設定されている場合は、何も起こりません。
PORT入出力の例
COL.PORTA.$0C #バンク0
COL.PORTB.$0D

MOV.PORTA.W   #ポートAの各ピンの電圧を読み込み

MOV.%10000100 #RB2,RB7にHigh、他にLowを出力
MOV.PORTB.F   #ポートBに出力

PORTA/PORTBの問題点

POTRA/PORTBは、特定の使い方をすると、誤動作を起こします。
特にBCF/BSF命令が、問題を引き起こすものとして知られています。
これらの命令は、定義上1ビットのみ変更するように見えます。
しかし、PORTA/PORTBについては、他のビットを変更してしまう可能性があります。
原因の一つは、前回書き込んだ値と異なる値を読み出す可能性があることです。
Highの電圧を出力するよう指定しても、実際に電圧が上がるまでには時間がかかります。
しばらくはLow扱いの電圧のままで、読み込むと0となります。
このとき、1を書き込んだビットが、読み出すと0になってしまっています。
もう一つの理由は、これらの命令が、8ビットまとめて読み出し/書き込みを行うことです。
変更するのは1ビットでも、他のビットも転送されるのです。
これらが、BCF/BSFとPORTA/PORTBの組み合わせの誤作動の原因です。
つまり、Highのはずのビットを、Lowとして読み出し、そのまま書き込んでしまうのです。
なお、これはHighとLowが逆でも起こりうる現象です。
さらに、MOVでWレジスタに移し、一部のビットを変えて出力する場合なども考えられます。

LATA/LATB

LATA/LATBは、PORTA/PORTBの欠点を補うためにつけられたレジスタです。
入力時と、出力ピン全てへの出力時には、同じ動作をします。
異なるのは、出力ピンの一部のみに出力する場合です。
このような場合には、LATA/LATBを使うのがよいでしょう。
実際の電圧ではなく、出力中の値を読み出すので、誤作動はおきません。
ただ、LATA/LATBはバンク2にあり、選択する手間がかかります。
不必要な場合には、PORTA/PORTBでよいです。
なお、LATA/LATBを使わず、実際に電圧が上がるまで待つ方法もあります。
しかし、コンデンサなどが含まれていると、かなり長時間待たなければなりません。
必要な場合にはLATA/LATBを使うようにしましょう。
LAT出力の例
COL.LATA.$0C #バンク2
COL.LATB.$0D

MBS.2
BSF.LATA.0   #RA0の出力をHighにする
             #他のピンには影響しない
MBS.0

実際の設定と入出力

実際には、起動時にTRISA/TRISBやANSELA/ANSELBをまとめて設定します。
これらを頻繁に変更することは、ほとんどありません。
主な処理の実行中に使うのは、PORTA/PORTBが大半です。

デジタル入出力

ここまで、HighとLowという言葉を用いて電圧や電位を説明してきました。
しかし、回路に電位が2つしか存在しないということはありません。
この項に出てくる値は、データシートのDC Characteristics直流特性の項に記載されているものを参考にしました。

入力時

以下、「電圧」はVssに対する相対電位を示します。
入力時には、概ねVddの15%より低い電圧がLowと判定されます。
また、Vddの25%の電圧+0.8[V]を超えると、Highと判定されます。
この2つのしきい値thresholdの間には幅があります。
ここに含まれる電圧を入力した場合、判定は不定です。
ですから、あいまいな電圧が入力されないように回路を組みましょう。
なお、入力してよい電圧の下限は-0.3[V]、上限はVdd+0.3[V]です。

出力時

出力時はより簡単で、VssまたはVddと出力ピンが接続されます。
ただし、25[mA]までしか流せないので、LED数個までしか駆動できません。
それ以上流す場合には、トランジスタなどで増幅してください。