Luminary Micro ― 2009年05月14日 21時34分16秒
SH2 SH7085 (4) iic (3) ― 2009年05月14日 22時03分35秒
通常は問題ないのだが開始条件発行後 ACK = 1 だった時、うまくいかない。
当然、停止条件発行後 開始条件を再発行するのだが開始条件再発行後の TEND が確認できない。
IIC2.ICCR2.BIT.IICRST でリセットしてもだめだ。
ハードウェアリセットしかない。
IIC の機能を使わず I/O で制御すると問題ないから、やはり何らかの不具合を持っているのだろう。
つまり、IIC コントローラに ACK = 1 を認識させてはだめだということか?
困った、腫れ物に触るような使い方をしなければならないらしい。
さて、次は SH7080 グループ ハードウェアマニュアルの図18.19 マスタ受信モードのフローチャート例 を見てみよう。
同様に、組み込んでみよう。
当然、停止条件発行後 開始条件を再発行するのだが開始条件再発行後の TEND が確認できない。
IIC2.ICCR2.BIT.IICRST でリセットしてもだめだ。
ハードウェアリセットしかない。
IIC の機能を使わず I/O で制御すると問題ないから、やはり何らかの不具合を持っているのだろう。
つまり、IIC コントローラに ACK = 1 を認識させてはだめだということか?
困った、腫れ物に触るような使い方をしなければならないらしい。
さて、次は SH7080 グループ ハードウェアマニュアルの図18.19 マスタ受信モードのフローチャート例 を見てみよう。
[1] SCL、SDAラインの状態判定 [2] マスタ送信モードに設定 [3] 開始条件発行 [4] 第1バイト(スレーブアドレス+R/W)の送信データの設定 [5] 1バイト送信終了待ち [6] 指定したスレーブデバイスからのアクノリッジの判定 [1] TENDをクリア、マスタ受信モードに設定 その後TDREをクリア * [2] 送信デバイスへのアクノリッジを設定 * [3] ICDRRダミーリード * [4] 1バイト受信完了待ち [5] (最後の受信-1)判定 [6] 受信データをリード [7] 最終バイトのアクノリッジ設定。 連続受信禁止(RCVD=1)に設定 [8] (最終バイト-1)の受信データをリード [9] 最終バイトの受信完了待ち [10] STOPフラグクリア [11] 停止条件発行 [12] 停止条件生成待ち [13] 最終バイトの受信データをリード [14] RCVDをクリア [15] スレーブ受信モードに設定 【注】 * [1]~[3]の処理中に割り込みが入らないようにしてください。 【補足】 1バイト受信の場合は[1]の後、[2]~[6]を省略し、[7]の処理へジャンプします。 [8]はICDRRダミーリードとなります。これもスムーズに行かない気がする。
同様に、組み込んでみよう。
[1] while( IIC2.ICCR2.BIT.BBSY!=0 ); [2] IIC2.ICCR1.BIT.MST = 1; IIC2.ICCR1.BIT.TRS = 1; [3] IIC2.ICCR2.BIT.BBSY = 1; IIC2.ICCR2.BIT.SCP = 0; [4] IIC2.ICDRT = SlaveAddress | IIC_DATA_W; [5] while ((IIC2.ICSR.BIT.TEND) == 0) ; [6] if(IIC2.ICIER.BIT.ACKBR != 0) return (1); IIC2.ICDRT = (unsigned char)((Address>>8) & 0xff); while ((IIC2.ICSR.BIT.TDRE) == 0) ; IIC2.ICDRT = (unsigned char)(Address & 0xff); while ((IIC2.ICSR.BIT.TDRE) == 0) ; IIC2.ICCR1.BIT.TRS = 1; IIC2.ICCR2.BIT.BBSY = 1; IIC2.ICCR2.BIT.SCP = 0; IIC2.ICDRT = SlaveAddress | IIC_DATA_R; while ((IIC2.ICSR.BIT.TEND) == 0) ; if(IIC2.ICIER.BIT.ACKBR != 0) return (1); [1] IIC2.ICSR.BIT.TEND = 0; IIC2.ICCR1.BIT.TRS = 0; IIC2.ICSR.BIT.TDRE = 0; [7] IIC2.ICIER.BIT.ACKBT = 1; IIC2.ICCR1.BIT.RCVD = 1; [8] dummy = IIC2.ICDRR; [9] while( (IIC2.ICSR.BIT.RDRF)==0 ); [10] IIC2.ICSR.BIT.STOP &= 0; [11] IIC2.ICCR2.BIT.BBSY = 0; IIC2.ICCR2.BIT.SCP = 0; [12] while ((IIC2.ICSR.BIT.STOP)==0) ; [13] data = IIC2.ICDRR; [14] IIC2.ICCR1.BIT.RCVD = 0; [15] IIC2.ICCR1.BIT.MST = 0; IIC2.ICCR1.BIT.TRS = 0;次第に自信がなくなってきたが、これでどうだ!
最近のコメント