SSブログ

I2CでLEDピカピカ (真)完全版 [ColdFire V2]このエントリーを含むはてなブックマーク#

2073158

以前、MCF52233付録基板 - I2CでLEDピカピカ完全版という記事でフラグの扱いをマスターしたと思っていたのですが、「機械語に移植したら動かない」という声が上がりました。 原因は、HCS08由来のI2CモジュールとColdFire由来のI2Cモジュールの違いにあったようです。

SilentCは、遅いのが取り得

件の記事で作成したプログラムでは、インタラプトフラグをクリアするために、I2SR[IIF]ビットに1を書き込んでいました。 ところが、このシーケンスが誤っていたようで、フラグがクリアされていなかったようです。 調べてみると、仕様の違いが明らかになりました。

  • MCF51QE128のIIFフラグは、"1"を書き込んでクリアする。
  • MCF52233のIIFフラグは、"0"を書き込んでクリアする。

まったく、正反対の仕様です。 このため、フラグがクリアされる前に次に転送するデータを書き込んでしまい、正常にデータが転送されなかったということのようです。 前回のプログラムにフラグを表示させるステートメントを追加すると、その様子がわかります。

  int  *pqspar =0x4010006c;
  char *i2adr  =0x40000300;
  char *i2fdr  =0x40000304;
  char *i2cr   =0x40000308;
  char *i2sr   =0x4000030c;
  char *i2dr   =0x40000310;
main(){
  int  i;
  *pqspar =0x00A0; // PQSPAR[3:2]=10 (i2c)
  *i2fdr = 0x38; // (x640)
  *i2cr  = 0x90; // See table
  write(0x03,0x00); // config as OUT
  #stop 0
  i=0;
  for(;;){
    if(Getc(0)=='q')break;
    Sleep(25);
    write(0x01,0xEF<<i);
    i=(i+1)&3;
  }
}
write(char com, char data){
  while ((*i2sr)&0x20) SystemSleep(); // Wait for BUS idle
  *i2sr  = 0x12; // Clear flags
  *i2cr |= 0x20; // START
  do {
    PrHexByte(*i2sr);PrStr(" ");
    *i2dr  = 0x40; // WRITE for 0100000
    while (!(*i2sr&0x02)); // Wait for IIF
    if (*i2sr&0x01) break; // Quit if no ACK
    *i2sr  = 0x12; // Clear flags
    PrHexByte(*i2sr);PrStr(" ");
    *i2dr  = com; // command
    while (!(*i2sr&0x02)); // Wait for IIF
    if (*i2sr&0x01) break; // Quit if no ACK
    *i2sr  = 0x12; // Clear flags
    PrHexByte(*i2sr);PrStr("\r\n");
    *i2dr  = data; // data
    while (!(*i2sr&0x02)); // Wait for IIF
  } while (0);
  *i2cr &= 0xDF; // STOP
}
OK
run
a2 a2 a6
a2 a2 a6
a6 a2 a6
a2 a2 a6
a2 a2 a6
a2 a2 a6

フラグがクリアされていれば、a0またはa4の値が並ぶはずです。

ここで、疑問が発生します。 問題のあるプログラムで、どうしてI2Cの通信が出来たのでしょうか? 答えは簡単。 SilentCの処理速度が遅いため、フラグを確認するまでにI2Cのパケットはすっかり送出されてしまっているため、データがぶつかることが無かったのです。 それでは、SilentCに匹敵するぐらい転送速度を遅くしたら、どうなるでしょうか。

write(char com, char data){
  while ((*i2sr)&0x20) SystemSleep(); // Wait for BUS idle
  *i2sr  = 0x12; // Clear flags
  *i2cr|=0x20;*i2dr=0x40;*i2dr=com;*i2dr=data;*i2cr&=0xDF;
}

ボーレートを最低にして、処理速度を最大限にするように努力しましたが、このプログラムでも通信は正常に動いていました。 どうやら、SilentCを使う限りは、「フラグをクリアしなかったことによる弊害」は確認できないようです。

修正版I2CでLEDピカピカのプログラム

「もう、フラグを見る必要なんか無いんじゃないか。」とも思いましたが、気を取り直して、修正プログラムを作成しました。

  int  *pqspar =0x4010006c;
  char *i2adr  =0x40000300;
  char *i2fdr  =0x40000304;
  char *i2cr   =0x40000308;
  char *i2sr   =0x4000030c;
  char *i2dr   =0x40000310;
main(){
  int  i;
  *pqspar =0x00A0; // PQSPAR[3:2]=10 (i2c)
  *i2fdr = 0x38; // (x640)
  *i2cr  = 0x90; // See table
  write(0x03,0x00); // config as OUT
  #stop 0
  i=0;
  for(;;){
    if(Getc(0)=='q')break;
    Sleep(25);
    write(0x01,0xEF<<i);
    i=(i+1)&3;
  }
}
write(char com, char data){
  while ((*i2sr)&0x20) SystemSleep(); // Wait for BUS idle
  *i2sr  = 0x00; // Clear flags
  *i2cr |= 0x20; // START
  do {
    PrHexByte(*i2sr);PrStr(" ");
    *i2dr  = 0x40; // WRITE for 0100000
    while (!(*i2sr&0x02)); // Wait for IIF
    if (*i2sr&0x01) break; // Quit if no ACK
    *i2sr  = 0x00; // Clear flags
    PrHexByte(*i2sr);PrStr(" ");
    *i2dr  = com; // command
    while (!(*i2sr&0x02)); // Wait for IIF
    if (*i2sr&0x01) break; // Quit if no ACK
    *i2sr  = 0x00; // Clear flags
    PrHexByte(*i2sr);PrStr("\r\n");
    *i2dr  = data; // data
    while (!(*i2sr&0x02)); // Wait for IIF
  } while (0);
  *i2cr &= 0xDF; // STOP
}

I2DRレジスタへの書き込みを行う前にI2SRレジスタを表示してくれる親切設計。 実際に使うときには、これらの表示ステートメントは削除してください。

OK
run
a0 a0 a4
a0 a0 a4
a4 a0 a4
a0 a0 a4
a0 a0 a4
a0 a0 a4
a4 a0 a4
a0 a0 a4
a0 a0 a4

ごらんのとおり、IIFフラグがクリアされているのが確認できました。

Interface誌のプログラムも

Interface 2008年9月号にも、I2Cを使って温度センサと通信を行うプログラムが掲載されています。 ところが、このプログラムでも「*sr|=2;」でフラグをクリアしたつもりになっています。 このプログラムも、SilentCの遅さに助けられているのですね。

参考文献

Interface (インターフェース) 2008年 09月号 [雑誌]

Interface (インターフェース) 2008年 09月号 [雑誌]

  • 作者:
  • 出版社/メーカー: CQ出版
  • 発売日: 2008/07/25
  • メディア: 雑誌

MCF52233に内蔵されているI2Cモジュールのフラグの操作は、HCS08シリーズのI2Cとは違っているので注意が必要です。 MC51QE128も、HCS08由来のモジュールを使っているので、MCF52233とは違っています。

HCS08 Unleashed: Designer's Guide to the Hcs08 Microcontrollers

HCS08 Unleashed: Designer's Guide to the Hcs08 Microcontrollers

  • 作者: Fabio Pereira
  • 出版社/メーカー: Booksurge Llc
  • 発売日: 2007/11/13
  • メディア: ペーパーバック

nice!(0)  コメント(0)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました