2013.12.17
前へ
次へ
ホームページトップへ戻る

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第526回]


●ANSELの設定はI/Oポート出力に影響を与えない?

前回からの続きです。
[第521回]の終わりのところで「I/Oポートを出力ポートとして使う場合には、ANSELは設定しなくてもよいはず」と一旦は書いたのですが、後で気になって確認をしてみましたところ、想定外の結果になってしまいました。

以下は前回に説明したことと同じですが、ここで発生している問題を把握していただくために、もういちど見ていただくことにいたします。

おとなしくANSEL、ANSELHをクリアして、アナログとデジタルを兼用しているポートを全てデジタルに設定したときのポートからの出力は、こんな波形だったのですが…。



ANSEL、ANSELHの設定のところをコメント文に直しただけで。
     org 0
st0
     goto start
;
     org 04
        goto int
;
        org 05
;
start
        movlw 20;bk1
;       movlw 60;bk3
        movwf STATUS
;       clrf ANSEL
;       clrf ANSELH
;       bcf STATUS,6;bk1
        movlw 64


こんなことになってしまいました。


そこであわててしまって前回の終りに、一旦は
「まちがったことを書いてしまいましたぁ。出力の場合でもやっぱりANSELの設定をデジタルにしておかなければいけませんでしたぁ。ごめんなさぁいぃ」
と書いたのですが、なんだか腑に落ちないものが残っておりました。


[出典]Microchip Technology Inc. PIC16F882〜887Data Sheet

だってですねえ。
ほらあ。
上の引用文でも、
The state of the ANSEL bits has no affect on digital output functions.
って書いてあるじゃありませんか。
さらに続けて、
A pin with TRIS clear and ANSEL set will still operate as a digital output,but the input mode will be analog.
と書いてあります。
それなら、やっぱりTRISで出力に設定したら、ANSELがアナログの指定になっていたって構わないじゃありませんか。

うむむ。
しかし…。
それじゃあ、最初のあの写真はなんなのさ?

あれはきっと何かの手違いで…。

手違いなどではありませんでした。
念のために注意深く再度テストを繰り返してみましたが、やっぱりANSELの設定を行なわない場合には、最初の写真のように出力がすぐに落ちてしまいます。

なぜだ…?

そこで、もう一度Data Sheetをよく読んでみましたところ、「おお。そういうことだったのか!」やっと合点がいきました。
やっぱりData Sheetはよく読まなければいけません。
肝心なことが、上の続きに書いてありました。

This can cause unexpected behavior when executing read−modify−write instructions on the affected port.

●READ MODIFY WRITE

read modify write はこの前のPORTAの説明のところにも書いてありました。


[出典]Microchip Technology Inc. PIC16F882〜887Data Sheet

左下から右上にかけてのくだりです。
Reading the PORTA register reads the status of the pins,whereas writing to it will write to the PORT latch.

つまり出力に設定したポートの値を読むときは、出力ラッチの値を読むのではなくて、その端子の状態を読むんですと!
同じことじゃないの?
って、同じじゃなかったのですよお。


[出典]Microchip Technology Inc. PIC16F882〜887Data Sheet

ほら。
この図を見ますと、なんとなくそのあたりの事情がわかってくるのではありませんか?
確かに、ANSELがアナログに設定されたままであっても、出力に影響はないようです。
しかし、もしもその出力の値を読み込もうとしたら…。
ANSELがアナログの場合にはアナログ入力をデジタルとして読んでしまうことになります。
そして、その場合には端子の状態に関わらず、’0’が読み込まれます(ひとつ上の引用文の「Note」参照)。
これでやっと疑問が解けました。

やっていたのですよお。
その「read−modify−write」というやつを。

下はこのプログラムのTIMER1割込みルーチンです(全体のプログラムリストは[第516回]にあります)。
int
     movwf savew
     swapf STATUS,w
        clrf STATUS
     movwf savests
;
     bcf STATUS,5;bank 0
        movlw 1
        xorwf PORTE,f;pulse out
        bcf T1CON,0;stop T1
        movf t1Hdata,w
        movwf TMR1H
        movf t1Ldata,w
        movwf TMR1L
        movlw 1
        movwf T1CON;start T1
intend
        clrf PIR1;***************
     swapf savests,w
     movwf STATUS
     swapf savew,f
         swapf savew,w
     retfie
;

movlw 1
xorwf PORTE,f
がその部分です。
このテクニックはあるビットの出力だけを反転させるときによく使います。
ここではPORTEのビット0の出力だけが反転するはずだったのですが…。
他のビットは一旦読み込んでそのまま出力されるべきところ、ANSELがアナログ設定のままだったために、読み込んだ時点でそのビットは(出力ラッチは’1’にもかかわらず)’0’が読み込まれてしまい、それが出力されてしまったのでした。

むむむ。
まさに、cause unexpected behavior でありました。

こういう予期せぬトラブルに悩まないためにも、やはり「ころばぬ先の杖」で、ANSEL、ANSELHは必ず設定しておくべきでありましょう。
さもないと、Microchip様のおっしゃっております通り、
This can cause unexpected behavior.
でありますぞ。

ワンボードマイコンでCP/Mを![第526回]
2013.12.17upload

前へ
次へ
ホームページトップへ戻る