今更恥ずかしくて聞けない、RL78/I1Eの簡易IIC通信を教えてください。

こんにちは、NAKAといいます。

 

すみませんどうもI2C通信とは相性が悪いみたいで、なかなかゆうことを聞いてくれません。
以前RXの時もつまづいて、原因もあやふやなまま動いてしまったのでそのままの経緯があります。

今回、RL78/I1Eで初、簡易I2Cですがなんか上手く受信できてないような気がします。

もし、愛と少々のお時間がありましたら、お付き合いお願いできませんでしょうか?


まず、RL78をマスタにし、接続した開発中のデバイス(スレーブ)の仕様は
スレーブアドレス 0x77
レジスタアドレス 0x03、0x04、0x05 の 3Byte のデータを読みたいのですが
オートインクリメントができるみたいで、こんな感じ


そして
/*************************************************************************
// 関数名 : fn_Init_IIC00(void)
// 動作 : I2Cシリアル通信の初期化
// 引数 :
// 作成 : NAKA  19.10.14
// 備考 :  SAU0   ユニット=0 ch0=IIC00 (P14⇒SDA00  P15⇒SCL00)
// ***********************************************************************/
void fn_Init__IIC00(void)
{
    SAU0EN = 1;      //クロック供給
    SPS0 = 0x0000;  //クロック選択

    ST0 |= 0x0001;  //IIC00停止
    IICMK00 = 1;     //IIC00割り込み禁止
    IICIF00 = 0;     //IIC00割り込み要求フラグクリア
    IICPR100 = 1;  //IIC00割り込みプライオリティ設定
    IICPR000 = 1;
 
    SIR00 = 0x0003;  //全てエラーフラグのクリア
    SMR00 = 0x0024;  //簡易I2Cモードに設定
    SCR00 = 0x8017;  //1stopビット、8ビットデータ長
    SDR00 = 0xC600;  //ボーレート設定
    SO0 |= 0x0101;  //_シリアルクロックを1から | シリアルデータを1から
   
    POM1 |= 0x10;  //ポートの設定
    P1 |= 0x30;
    PM1 &= 0xCF;
 
    IICMK00 = 0;     //IIC00割り込み許可
 
}


※割込みの中では f_IIC00というフラグを立ててるだけです。(ベクタの設定もやってます。)
/************************************************************************/
/* IIC00の割り込み関数            */
/************************************************************************/
void __near IIC00_INT(void)
{
 IICIF00 = 0;     //IIC00割り込み要求フラグクリア
 f_IIC00 = 1;     //IIC通信完了フラグON!
}


こんな感じで設定して、

 

MAINの中で1秒毎に


    //①アドレス・フィールド送信
    SO0 &= 0xFFFE;              //スタートコンデション発行   SO00=0
    for(j=0;j<=10;j++)            //ウエイト
    {
     __nop();
    }
    f_IIC00 = 0;                       //IIC完了フラグクリア
    SO0 &= 0xFEFF;                 //クロックを"0"にして通信準備 CKO00=0
    SOE0 |= 0x0001;                //シリアル出力許可レジスタを許可 SOE00=1
    SS0 |= 0x0001;                 //シリアル動作許可状態にする SS00=1
   
    SCR00 &= ~0xC000;              //送受信を止める  TXE00=0 RXE00=0
    SCR00 |= 0x8000;               //送信状態にする   TXE00=1    
   
    SIO00 = (0x77 << 1) | 0x00;    //スレーブアドレスデータを入力****暫定 スレーブアドレス0x77 Wite:0 Read:1
    while(!f_IIC00)                //IIC完了割込み待ち
    {
     __nop();    
    }
    f_IIC00 = 0;                   //IIC完了フラグクリア
    if((SSR00 & 0x0002) != 0)      //ACK確認
    {
     c_ARK_ERR++;                  //エラー処理
    }
    //②レジスタアドレスデータ送信
    SIO00 = 0x03;                  //レジスタアドレスデータを入力
    while(!f_IIC00)                //IIC完了割込み待ち
    {
     __nop();    
    }
    f_IIC00 = 0;                   //IIC完了フラグクリア
    if((SSR00 & 0x0002) != 0)      //ACK確認
    {
     c_ARK_ERR++;                  //エラー処理
    }
   
    //③データ受信   
    SIO00 = (0x77 << 1) | 0x01;    //スレーブアドレスデータを入力****暫定 スレーブアドレス0x77 Wite:0 Read:1
    while(!f_IIC00)                //IIC完了割込み待ち
    {
     __nop();    
    }
    f_IIC00 = 0;                   //IIC完了フラグクリア
    if((SSR00 & 0x0002) != 0)      //ACK確認
    {
     c_ARK_ERR++;                 //エラー処理
    }
   
    ST0 |= 0x0001;                //シリアル動作停止状態にする  ST00=1
    SCR00 &= ~0xC000;             //送受信を止める    TXE00=0 RXE00=0
    SCR00 |= 0x4000;              //受信状態にする   RXE00=1
    SS0 |= 0x0001;                //シリアル動作許可状態にする SS00=1   
   
   
    SIO00 = 0xFF;                //ダミーデータ書き込み
    while(!f_IIC00)              //IIC完了割込み待ち
    {
     __nop();    
    }
    f_IIC00 = 0;                 //IIC完了フラグクリア
    IIC_RX_DATA[0] = SIO00;   
   
    SIO00 = 0xFF;                //ダミーデータ書き込み
    while(!f_IIC00)              //IIC完了割込み待ち
    {
     __nop();    
    }
    f_IIC00 = 0;                //IIC完了フラグクリア
    IIC_RX_DATA[1] = SIO00;
   
    //最後なので
    SOE0 &= 0xFFFE;             //シリアル出力許可レジスタを停止
   
    SIO00 = 0xFF;               //ダミーデータ書き込み
    while(!f_IIC00)             //IIC完了割込み待ち
    {
     __nop();    
    }
    f_IIC00 = 0;               //IIC完了フラグクリア
    IIC_RX_DATA[2] = SIO00;

    //④ストップコンディション発行
    ST0 |= 0x0001;            //シリアル動作停止状態にする  ST00=1
    SOE0 &= 0xFFFE;           //出力禁止状態    SOE00=0
    SO0 &= 0xFFFE;            //SDA出力を0にする   SO00=0
    for(j=0;j<=100;j++)       //ウエイト HWM-P649   必要らしい
    {
     __nop();
    }   
    SO0 |= 0x0100;            //クロック出力を1にする   CKO00=1
    for(j=0;j<=10;j++)        //ウエイト HWM-P649   必要らしい
    {
     __nop();
    }
    SO0 |= 0x0001;             //SDA出力を1にする   SO00=1

 


ってやるとIIC_RX_DATA[0]~[2]に受信データが入っていることを期待していますが
全部 ダミーと同じ 0xFF が入ってます。

 

エラー処理は取り合えず保留でACKが帰らなかったったら
c_ARK_ERRっていうカウンタをインクリメントすることにしてます。
c_ARK_ERRがインンクリメントされないので、ACKは受信できてそうだし、
(※スレーブアドレスを0x77以外にするとACKは来ずにc_ARK_ERRはインクリメントされる)
f_IIC00フラグも立つので割込みも発生している感じです。


なんかあんぽんたんなことをやってる感じでしょうか?

Parents
  • チョコです。
    さっと見始めたところですが,2つほど気になるところがあります。
    スレーブは,MCUでしょうかそれとも専用のスレーブでしょうか。
    RL78の簡易I2Cではスレーブからウエイトをかけることができないので,1バイトごとの通信の間隔をマスタ側で確保(通信の間に時間を空ける)必要があります。
    次がI2Cの基本に関する重大な欠陥です。②の処理に引く続いて,③でスレーブ・アドレスを送信開始しているつもりのようですが,ここは,②の処理の後に,リスタート(スタート・コンディションを発行)してから③を処理すべきです。このままでは,単にレジスタアドレス0x03に0xEFというデータを書き込んでいるだけです。
  • チョコ先生! おはようございます。NAKAです。

    いつも本当にありがとうございます。
    昨日は、終日出張でしたのでお礼が遅くなりました。
    やっぱり、NAKAはどこかぬけてますね(~_~;)お恥ずかしい!(~_~;)

    修正してみます。
Reply
  • チョコ先生! おはようございます。NAKAです。

    いつも本当にありがとうございます。
    昨日は、終日出張でしたのでお礼が遅くなりました。
    やっぱり、NAKAはどこかぬけてますね(~_~;)お恥ずかしい!(~_~;)

    修正してみます。
Children
No Data