Q&A (電気電子)

【PIC】PICマイコンのPORTAレジスタとLATAレジスタの違いについて紹介する -リード・モディファイ・ライトについて説明する-

備忘録も兼ねてメモしておきます。

関連記事
【PICマイコン】PICマイコンの 各種機能の使い方を紹介する

PICマイコン勉強中。 ぼちぼち更新していく予定。 PICマイコンの使い方をまとめてみる 割とネットにサンプル集がない & 自分で新規処理作ろうとしたときに設計背景思い出したくなることが多々あ ...

続きを見る

PORTAとLATAは何が違うんや。

マイコンのポートの電圧レベルを反映するのがPORTレジスタ、
マイコンのポートに出力予定の設定データを保存しているのがLATAレジスタ、という違いがあります。

ポートへの入力を読み取る際はPORTレジスタしか使用できませんが、書き込みの際にはPORTとLATの2つのレジスタで実行することが可能です。

そうなると、「書き込みの際、結果が同じになるなら実際何が違うの?」という話になってきます。

どちらが書き込みに適しているかについて、結論から言うと、

・読み取り時はPORTA (LATAからは読み取り不可。)
・書き込み時はLATA  (PORTAでも書き込みできるけど、LATAを使う。)

となっています。

今回はこの辺について説明、まとめをしてみます。

データシートを読んでみる

まず最初にデータシートを確認してみます。

今回PIC16F1827について確認しますが、I/O PORTSの章を見てみましょう。

ここでの文章について、肝になるのは下記の記述です。

データラッチ(LATxレジスタ)は、I/Oピンが駆動している値に対するリード・モディファイ・ライト操作に役立ちます。
LATxレジスタへの書き込み操作は、対応するPORTxレジスタへの書き込み操作と同じ効果があります。
LATxレジスタの読み出しはI/O PORTラッチに保持されている値を読み出し、PORTxレジスタの読み出しは実際のI/Oピンの値を読み出します。

PORTAへ書き込むのとLATAに書き込むのとでは、リード・モディファイ・ライトに影響を受けるか否かが、大きく変わってきます。

今回はこのリード・モディファイ・ライトとPORTA、LATAの関係性について、紹介してみます。

リード・モディファイ・ライトとは?

データシートに記載されていた、リード・モディファイ・ライト(Read-Modify-Write)について、簡単に説明してみます。

リード・モディファイ・ライトとは、レジスタの値を更新する際の3つの手順になります。

レジスタに数値を書き込んでポートの出力を更新する際、実は、「読み取り」「加工」「書き込み」の3つの手順が走っています。
(書き込みにおいても、読み取り作業が含まれている。)

例えばPORTAのビット0を更新したい場合に、下記のようなコードを書いたとします。

PORTA = 0x01;

このコードでは、一見、PORTAのビット0だけを書き換えしているように見えるのですが、実際の動作を意訳してみると下記のようになっています。
(厳密にはもう少し異なると思いますが、動作のイメージとして処理を作っています)

unsigned char temp;
unsigned char input;

/* ユーザーの更新したい処理内容 */
PORTA.bit0 = 0x01;     /* 0b0000-0001 */

==========================================================
実際のマイコン内の動き
==========================================================
/* リード */
temp = PORTA;          /* 0b0110-0100 */

/* モディファイ */
input = PORTA.bit0;    /* 0b0000-0001 */
temp = temp + input;   /* 0b0110-0100 + 0b0110-0101 */

/* ライト */
PORTA = temp;

ソースコード上では単純に1ビットを書いたとしても、実際にはレジスタ全体を読み出し、変更点を反映(加工)し、書き込む。。。。

前回までの値を確認してから更新処理が走っている・・・という動作になっています。

PORTAに書き込むのとLATAに書き込むので、何が異なるのか?

リード・モディファイ・ライトについての説明は以上です。

続いて、PORTAに書き込むのと、LATAに書き込むのとで、何が異なるのか考えてみます。

まずはブロック図を確認してみます。

このブロック図から、下記のことがわかります。

・LATAとPORTAの書き込み結果はともにData Registerへ入力される
・Data Registerの出力は、LATAレジスタに保存される
・Data Registerの出力は、I/O pinへ伝わる
・I/O pin の状態は、PORTAで読み取れる

ここで、それぞれのレジスタへの書き込み操作を行った場合についてですが、先ほどのリード・モディファイ・ライトの「リード工程」
について考えてみると、下記のようになります。

・LATAに書き込み:LATAでリード・モディファイ・ライト
・PORTAに書き込み:PORTAでリード・モディファイ・ライト

ともに、Data Registerに書き込みを行い、ポートの出力状態が更新されるという動作は同じでも、
リードの工程に読み出す値が、どちらのレジスタに書き込むかによって異なります。

レジスタに連続して書き込んだ場合を想定してみる

なんとなく答えが浮かんできたかと思いますが、最後まで説明してみます。

下記のようなソースコードを作成した時に、出力がどうなるか考えてみます。

LATAへの連続書き込み

LATA |= 0x01;
LATA |= 0x02;
LATA |= 0x04;
LATA |= 0x08;
LATA |= 0x10;
//LATA |= 0x20;    /* RA5は読み取り専用ポート... */
LATA |= 0x40;
LATA |= 0x80;

ソースコードの動作は、LATAレジスタの0から7bit目までを、連続して1ビットずつ書き込んでいるだけです。

各行ごとに、マイコンはLATAレジスタの値を読み出し、加工し、書き込みを行っていきます。

LATAは前回までにData Registerに書き込んだ値がすぐに反映される「出力ラッチ」であるため、
2行目以降では、1つ前の行で更新された値を確実にリードしてから、モディファイ・ライトできます。

PORTAへの連続書き込み

では、下記のソースコードを実行した場合はどうでしょうか?

PORTA |= 0x01;
PORTA |= 0x02;
PORTA |= 0x04;
PORTA |= 0x08;
PORTA |= 0x10;
//PORTA |= 0x20;    /* RA5は読み取り専用ポート... */
PORTA |= 0x40;
PORTA |= 0x80;

処理内容としては、先ほどと同じく0~7bit目までを、連続して1ビットずつ書き込んでいるだけです。

ただし、LATAと異なり、リード・モディファイ・ライトのリード工程において、
Data Registerの設定値(出力ラッチ)ではなく、現在のポート状態をそのまま読み出します。

ここで、マイコンの処理の動作速度を考えてみます。

マイコンの動作クロックは、遅くても数MHz程度あるものが一般的です。

上記の8行の処理も、時間的にはとても短い時間で完了してしまいます。

これに対して、マイコンのピンの電圧の変化はどうでしょうか?

基本的に現実の素子は、抵抗分やインダクタンス、その他の要因によって、出力を0秒で瞬時に切り替えることはできません。

このため、PORTAレジスタに書き込みを行っても、ポートの状態はすぐには変化できず、次のリード工程において、
まだ電圧が立ち上がっていないポートの電圧レベルを読み出します。

PORTAとLATAへの連続書き込み操作における結果の違い

このため、上記の例に挙げた2つの処理を実行すると、下記のような結果になります。
(実際にプログラムを書き込んで動作させても、実際にこうなることを確認できます。)

LATA |= 0x01;
LATA |= 0x02;
LATA |= 0x04;
LATA |= 0x08;
LATA |= 0x10;
//LATA |= 0x20;    /* RA5は読み取り専用ポート... */
LATA |= 0x40;
LATA |= 0x80;
➡ポートRA0~RA4,RA6~RA7の出力電圧が、すべてHIレベルになる

/*============================================================================================*/

PORTA |= 0x01;
PORTA |= 0x02;
PORTA |= 0x04;
PORTA |= 0x08;
PORTA |= 0x10;
//PORTA |= 0x20;    /* RA5は読み取り専用ポート... */
PORTA |= 0x40;
PORTA |= 0x80;
➡ポートRA7のみが、HIレベルになる

※より厳密には、ポートの電圧レベルがData Registerへの書き込みと同時に変化するように見えるぐらい、処理時間が遅い(各行の間の時間が長い=クロック周波数が非常に遅い)場合は、PORTAへの書き込みでも全部のポートが更新されます。
そんなにクロック周波数を下げるケースはあまりないかと思います・・・・

まとめ

最後にまとめです。

今回はリード・モディファイ・ライト、PORTAとLATAへの書き込みの違いについて紹介してみました。

リード・モディファイ・ライトにおける問題というと、値の更新中に割り込みが入ったときに意図しない値に書き換わる・・・・といった、

もう少し難しい条件下で議論されることが多い気がしますが、PICの場合はレジスタ構成の都合で簡単なソースコードで再現できてしまいます。。。。

いいか悪いかはさておき、説明用の題材としては申し分ないですね・・・

それでは、また。

関連記事
【PICマイコン】PICマイコンの 各種機能の使い方を紹介する

PICマイコン勉強中。 ぼちぼち更新していく予定。 PICマイコンの使い方をまとめてみる 割とネットにサンプル集がない & 自分で新規処理作ろうとしたときに設計背景思い出したくなることが多々あ ...

続きを見る

-Q&A (電気電子)
-, , ,