SyntaxHighlighter

---SyntaxHighlighter ウィジェット---

2015年3月2日月曜日

今日の教訓

教訓: PICのPORTxレジスタのBSF,BCF問題はC言語でも変わらず生きている。
    入力ピンを念のため初期化するなら、一括で設定するか、別途変数を作る。

ちょっとわけあってこんなプログラムをPICのX8Cで組んでいました
PICを触るのはまた久しぶり、しかも短時間だからどんどん忘れている。

void digitalWrite(int p,int x)
{
    if(p == sda0)
    {
        RB4 = x;
    }else if(p == scl0){
        RB5 = x;
    }
}

void I2C_START_()
{
   digitalWrite(sda0,LOW);
   digitalWrite(scl0,LOW);

   pinMode(scl0,INPUT);

   ...

}


そうです、下にArduinoで組んだI2Cマスタをそのまま移植しています。
ここで問題、このプログラムは正常に動作するでしょうか?

解:しない

どういう挙動になるか?

*理想
RB4=0 でポートB4が LOWに。
RB5=0 でポートB5が LOWに。

ポートは入力に設定されているので、直ぐに出力には影響しないが
ポートを入力にするとHi-Z、出力にするとLowになる。

*現実
RB4=0 でポートB4が LOWに。
出力・入力レジスタが共有で、BCFで書き換わるため
読み出し→書き換え→書き込みが行われるため、プルアップされているRB5がHIGHに

RB5=0 でポートB5が LOWに。
出力・入力レジスタが共有で、BCFで書き換わるため
読み出し→書き換え→書き込みが行われるため、プルアップされているRB4がHIGHに

ポートは入力に設定されているので、直ぐに出力には影響しないが
ポートを入力にするとRB4、RB5ともにHi-Z

出力にするとRB4がHigh、RB5がLowになる。


そりゃうまく動かないわけだ。

しかも、お陰で3.3Vで動いているLCDの入力ピンに5Vを掛けたことに。
とりあえず、時間が短かったせいか壊れてはいないようです。

*解決方法
void digitalWrite(int p,int x)
{
   PORTB=0; //他なにもつながってないし
}

AVRでは入出力のレジスタが分かれているので起こらないし。
新しい品番のPICではLATxという出力専用レジスタがあるのでやっぱり起こらない。

結局これに5時間くらい悩まされて頭が痛くなった。
やっぱりくせがあるぜ8bitのPIC...


*おまけ

39:            void digitalWrite(int p,int x)
40:            {
41:                if(p == sda0)
0535  0870     MOVF __pcstackCOMMON, W
0536  0471     IORWF 0x71, W
0537  1D03     BTFSS STATUS, 0x2
0538  2D43     GOTO 0x543
42:                {
43:                    RB4 = x;
0539  1C72     BTFSS x, 0x0
053A  2D3F     GOTO 0x53F
053B  1283     BCF STATUS, 0x5
053C  1303     BCF STATUS, 0x6
053D  1606     BSF PORTB, 0x4
053E  0008     RETURN
053F  1283     BCF STATUS, 0x5
0540  1303     BCF STATUS, 0x6
0541  1206     BCF PORTB, 0x4
44:                }else if(p == scl0){
0542  0008     RETURN
0543  0370     DECF __pcstackCOMMON, W
0544  0471     IORWF 0x71, W
0545  1D03     BTFSS STATUS, 0x2
0546  0008     RETURN
45:                    RB5 = x;
0547  1C72     BTFSS x, 0x0
0548  2D4D     GOTO 0x54D
0549  1283     BCF STATUS, 0x5
054A  1303     BCF STATUS, 0x6
054B  1686     BSF PORTB, 0x5
054C  0008     RETURN
054D  1283     BCF STATUS, 0x5
054E  1303     BCF STATUS, 0x6
054F  1286     BCF PORTB, 0x5
46:                }
0550  0008     RETURN
47:            }

0 件のコメント:

コメントを投稿