IOのビット操作命令の問題
PICではPORTBに値を書くと結果は出力のラッチに書かれ、
PORTBを読むと現在のポートの値が返る。
出力のラッチの値を読むための専用の線は存在しない。
ビット操作命令(BCF/BSF)を使うと、ポートから8bitの値を読み、特定のビッ
トをセットした後、結果の8bitを出力のラッチに書く。そのため、セットするビッ
ト以外で、入力モードになっているビットはポートからの入力の影響
を受ける。
よって、ポートを入出力兼用とする場合は出力のラッチの値がポートの入力に
より変化してしまうので注意が必要。他のポートでも同じことが言える。
出力ラッチの値が変化する例 出力ポートのラッチの値
movlw 0 ; W=00000000
bsf STATUS,RP0 ; バンク切り替え 01
movwf TRISB ; ポートBは全て出力
bcf STATUS,RP0 ; バンク切り替え 00
movlw 0 ; W=00000000
movwf PORTB ; 出力値セット 00000000
movlw 2 ; W=00000010
bsf STATUS,RP0 ; バンク切り替え 01
movwf TRISB ; ポートBのbit1のみ入力
bcf STATUS,RP0 ; バンク切り替え 00
bsf PORTB,0 ; PORTBのbit0を1にセット
; この時にbit1の入力が0だと 00000001 になる
; この時にbit1の入力が1だと 00000011 になる
movlw 0 ; W=00000000
bsf STATUS,RP0 ; バンク切り替え 01
movwf TRISB ; ポートBは全て出力
bcf STATUS,RP0 ; バンク切り替え 00
; ポートBのbit1はbsf実行時の入力が反映される
AVRでは出力のラッチの値を読み書きするポート(PORTB)と、
ポートの値を読むためのポート(PINB)が別に用意されている。
PORTBは読み書きができる。PINBは読み込みのみ。
IOのビット操作命令(SBI/CBI)でPORTBをいじると、
出力のラッチの値8bitを読み、特定のビットをセットした後、結果の8bitを出
力のラッチに書き戻す。
そのためポート入力の影響を受けず、上記のような問題は生じない。
AVRでの上記と同様の例
ldi r16,0b11111111 ; r16=11111111
out DDRB,r16 ; ポートBは全て出力
ldi r16,0 ; r16=00000000
out PORTB,r16 ; 出力値セット 出力=00000000
ldi r16,0b11111101 ; r16=11111101
out DDRB,r16 ; ポートBのbit1のみ入力
sbi PORTB,0 ; PORTBのbit0を1にセット
; 出力は必ず 00000001 になる
ldi r16,0b11111111 ; r16=11111111
out DDRB,r16 ; ポートBは全て出力
; 出力は必ず 00000001 になる