”かふぇルネ“はルネサス製品に関してユーザ同士が自由に会話をするツールであり、回答者はルネサス社内外の方たちとなります。ルネサス製品やソリューションに関して正式な回答をご希望の場合は、ルネサス技術サポート問合せをご使用ください。

RL78/G13におけるCS+コード生成の簡易I2Cについて

失礼いたします。

MPU6050の慣性計測ICを用いるために簡易I2Cをコード生成にて使用できないかを実験中です。

データシートや他チップ用サンプルを覗いた限り下記に示すMain文で読めるものと考えたのですが上手くいきません。

データの行き来はE1エミュレータにて確認していますがR_IIC11_Master_Sendの各種割り込みは起動しています。

しかし、R_IIC11_Master_Receiveの完了割り込みは起動したりしなかったりするうえ、帰ってくるアドレスには何も入力されていません。


//起動
txd[0] = 0x6B*2;
txd[1] = 0x00;
R_IIC11_Master_Send(DeviceID,txd,2);
完了割り込み待ち
while (1U)
{
//IC読み出しメモリ番地指定
txd[0] = 0x3B*2;
R_IIC11_Master_Send(DeviceID,txd,1);
完了割り込み待ち
//IC読み出し要求
R_IIC11_Master_Receive(DeviceID,rxd,14);
完了割り込み待ち
50ms待機
}

大変恐縮ですが、ご回答よろしくお願いいたします。

  • チョコです。

    「通信完了待ち」を「完了割り込み待ち」で行われているようですが、INTIIC11は1バイト転送完了で発生します。

    R_IIC11_Master_SendやR_IIC11_Master_Receiveではスレーブアドレスの送信完了で発生するのですが、ここらは理解していますか。

    これまでも何度も言っていますが、コード生成の通信関係の処理には大いに問題があります。

    そこで、個人的にはコード生成は初期設定だけしか使いません。APIは全て自前でやっています。サンプルプログラム等の以下のプログラムが参考になるかと思います。

    IIC通信のマスタ側(RL78/G13の簡易IIC版)改 2C

    プロジェクトをzipにして添付してもらえれば、具体的なコメントができるのですが。

    以上

  • チョコ様

    お返事ありがとうございます。
    URL先を拝見いたしました。量が多いので理解するのに少々かかりそうです。

    プロジェクトですが、多くは記述していないためこの場に記述いたします。
    投稿時から割り込み部分をディレイに変えております。

    void main(void)
    {
    R_MAIN_UserInit();
    /* Start user code. Do not edit comment generated here */


    txd[0] = 0x6B*2;
    txd[1] = 0x00;
    IMU_IIC11_Send(DevicdID,txd,2);


    while (1U)
    {

    IMU_IIC11_Receive(DevicdID,MPU6050_AX*2,rxd,14);

    tag += 1;
    }
    /* End user code. Do not edit comment generated here */
    }

    void IMU_IIC11_Send(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num)
    {
    int i;
    SCR03 = 0xC000;
    R_IIC11_StartCondition();
    SIO11 = adr & 0xFE;
    wait_5us();
    for(i = 0; i < tx_num; i++)
    {
    SIO11 = tx_buf[i] & 0xFE;
    wait_5us();
    }
    R_IIC11_StopCondition();
    }

    void IMU_IIC11_Receive(uint8_t adr, uint8_t mem, uint8_t * const rx_buf, uint16_t rx_num)
    {
    int i;
    SCR03 = 0xC000;
    R_IIC11_StartCondition();
    SIO11 = adr | 0x01;
    wait_5us();
    R_IIC11_StopCondition();
    R_IIC11_StartCondition();
    for(i = 0; i < rx_num; i++)
    {
    SIO11 = (mem + 0x02 * i) | 0x01;
    wait_5us();
    rx_buf[i] = SIO11 & 0xFF;
    }
    R_IIC11_StopCondition();
    }

  • チョコです。

    MPU6050のデータシートを眺めると、I2Cバスでの書き込みは以下のようにスレーブアドレスの次にRA(レジスタアドレス)を送信し、その後にレジスタに書き込むデータを送信するという一般的なシーケンスです。

    読み出しは以下のようになっており、これも、最初にRA(レジスタアドレス)を設定するために書き込みを行い、リスタートして読み出しモードでスレーブアドレスを送信し、引き続いてレジスタの内容を読み出す動きです。これも一般的なアクセス方法です。

    MPU6050は使ったことがないので、netでArduinoでの使用例を探してみました。
    比較的簡単そうだったのは「メカトロDIYチャレンジ」でしたので、そこの内容を参考にしてみます。

    MPU6050をArduinoで使う①入門編 | メカトロDIYチャレンジ(Mechatro DIY Challenge) (mechadiy.com)

    setup()関数は以下のようになっていました。

    最初にMPU6050のレジスタ0x6bに0x00書き込むことで、MPU6050を起動するようです。Ouraさんのプログラムでは、なぜかRAが「0x6b」ではなく、「0x6B*2」と異なっています。Arduinoではスレーブアドレスは7ビットで、RL78では8ビットなので、0x68を2倍するはいいのですが、RAはそのまま0x6bとすべきは。データシートでMPU6050の内部レジスタのアドレスを確認できていないので、理由が分かりません。(もしかしたら、データが16ビット長なので、2倍したのですか。)

    txd[0] = 0x6B*2;
    txd[1] = 0x00;
    IMU_IIC11_Send(DevicdID,txd,2);

    また、ここで呼び出している IMU_IIC11_Send関数ですが、以下のようになっています。最初にSCR03のbit15とbit14を同時に1にしていますが、簡易IICモードではこれはやってはいけなかったはずです。なにを参考にしてこのような処理を行ったのでしょうか。

    void IMU_IIC11_Send(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num)
    {
    int i;
    SCR03 = 0xC000;
    R_IIC11_StartCondition();
    SIO11 = adr & 0xFE;
    wait_5us();
    for(i = 0; i < tx_num; i++)
    {
    SIO11 = tx_buf[i] & 0xFE;
    wait_5us();
    }
    R_IIC11_StopCondition();
    }

    さらに、データ受信でもSCR03を0xC000にしているのは間違いです。

    void IMU_IIC11_Receive(uint8_t adr, uint8_t mem, uint8_t * const rx_buf, uint16_t rx_num)
    {
    int i;
    SCR03 = 0xC000;
    R_IIC11_StartCondition();
    SIO11 = adr | 0x01;
    wait_5us();
    R_IIC11_StopCondition();
    R_IIC11_StartCondition();
    for(i = 0; i < rx_num; i++)
    {
    SIO11 = (mem + 0x02 * i) | 0x01;
    wait_5us();
    rx_buf[i] = SIO11 & 0xFF;
    }
    R_IIC11_StopCondition();
    }

    細かいところがきちんとできていないので、正常には動作しません。

    通常は、割り込み処理で細かな制御を行うのですが、それをやっていないように見えます。

    一度、動作しているサンプルプログラムをきちんと読まれることを推奨します。

    以上

  • 取り急ぎ回答を致します。

    なぜかRAが「0x6b」ではなく、「0x6B*2」と異なっています。

    の部分につきましてデータシート内のシリアルデータレジスタを15-9までが分周、

    7-1が受送信用データ、0がR/W判別と考えておりました。

    データ受信でもSCR03を0xC000にしているのは間違いです

    上記についても同様でシリアルデータレジスタのみでI2C制御可能と考えておりました。

    そのため受送信をオンにしておけばよいものと…

    現在は示して頂いたサンプルをIIC11に変えて試行中です。

    割り込み(INTIIC11、INTTM0)がうまく起動しないためデータシートとにらめっこをしております。