かふぇルネのIICサンプルプログラムを改造したが,EEPROM (24FC6) の連続書き込みが不安定

皆様,

G13(CCRL)にてチョコさんのIICサンプルプログラムのMD_STATUS put_data_IIC00( uint8_t s_addr, uint8_t buffer1, uint8_t buffer2)を修正し,以下のプログラムを作成しました.

これはEEPROMのByte Writeを行うためのものです.これを5msのインターバルをおいて連続的に書き込むと,非常に不安定で正常に書き込めないことが多発しています.buffer1, buffer2 がEEPROMのアドレス,buffer3がデータです.ストップコンデイション云々の問題でしょうか?

ご指導お願いします.

=======

MD_STATUS put_3byte_IIC00( uint8_t s_addr, uint8_t buffer1, uint8_t buffer2, uint8_t buffer3)
{

    MD_STATUS status;
    //uint8_t work1, work2;
    
    //work1 = (uint8_t) ((buffer2 >>8) & 0x00FF);
    //work2 = (uint8_t) (buffer2 & 0x00FF);
    
    g_write_data[0] = buffer1;       /* set data1       */
    g_write_data[1] = buffer2;         /* set data2       */
    g_write_data[2] = buffer3;         /* set data3       */
    
    /*--------------------------------------
     start transmission
     --------------------------------------*/
    
     
    status = R_IIC00_Master_Send(s_addr, (uint8_t *__near)g_write_data, 3);
    
    if( IIC_SUCCESS == status )         /* check start successfully     */
    {
        
        /*--------------------------------------
         transmit start and
         wait for transmission end
         --------------------------------------*/
        
        do
        {                               /* wait for transmission end    */
            
            status = R_IIC00_check_comstate(); /* get IIC status          */
            
        }while( IIC_USING == ( status & IIC_STS_MASK ) );
        
        /*
         release IIC  bus
         */
        R_IIC00_StopCondition();          /* issue stop condition         */
        
    }
    else
    {
        /* do nothing */
    }
    
    return (status);
    
}

Parents Reply Children
  • (追加) アドレスも関係ないようです.

  • チョコです。

    どこをどのように改造したのでしょうか。全体像 が分かるような情報(プロジェクト)を開示してもらえませんか。

    変な改造を行っていると動作は不定です。

    また、通信速度はいくつで、プルアップ抵抗値は何Ωでしょうか。

    ところで24FC6は24FC64の間違いですよね。

    以上

  • チョコさま

    毎回お世話になります.

    replyが当方にメールされていなかったようで返答が遅れました.

    EEPROMは,24FC64でしたが,deviceが悪いと思い,これを現在は24C256に交換しました.

    コードは以下のとおりです.

    1アドレスに1バイト書き込み,1バイト読むというコードに変更しました.

    以前intを書き込むプログラムは,アドレス指定に配列を使っていました.これが悪かったようで,下のコードでは,uint8_tを使用しいます.

    このプログラムでは,書き込み及び読み込みは一応動作します.一応というのは,次のような現象があります.

    E1エミュレータを使用していますが,例えばアドレスは同じにして,書き込むデータを変更して[F6] build and downloadし実行してもデータは変更されません.Disconnect from Debugger [Shift F6]を行い,再度[F6]を行うと正しく書き込みができます.

    EEPROMの問題か,あるいはプログラムの問題なのか分かりません.ご指導お願いします.

    void write_data_byte(uint8_t i2c_adr, uint16_t rom_adr, uint8_t data)
    {
        
        uint8_t adr_high, adr_low;

        adr_high = (uint8_t) (rom_adr >> 8 );
        adr_low = (uint8_t) (rom_adr & 0xFF);
        
        put_3byte_IIC00(i2c_adr, adr_high, adr_low, data);
        wait_10ms();

    }

    uint8_t read_data_byte(uint8_t i2c_adr, uint16_t rom_adr)
    {
        uint8_t adr_high, adr_low, data;

        adr_high = (uint8_t) (rom_adr >> 8 );
        adr_low = (uint8_t) (rom_adr & 0xFF);

        put_data_IIC00(i2c_adr, adr_high, adr_low);
        read_byte_IIC00(i2c_adr, &data);
        return data;
    }

    MD_STATUS put_3byte_IIC00( uint8_t s_addr, uint8_t buffer1, uint8_t buffer2, uint8_t buffer3)
    {

        MD_STATUS status;
        //uint8_t work1, work2;
        
        //work1 = (uint8_t) ((buffer2 >>8) & 0x00FF);
        //work2 = (uint8_t) (buffer2 & 0x00FF);
        
        g_write_data[0] = buffer1;         /* set data1       */
        g_write_data[1] = buffer2;         /* set data2       */
        g_write_data[2] = buffer3;         /* set data3       */
        
        /*--------------------------------------
         start transmission
         --------------------------------------*/
        
         
        status = R_IIC00_Master_Send(s_addr, (uint8_t *__near)g_write_data, 3);
        
        if( IIC_SUCCESS == status )         /* check start successfully     */
        {
            
            /*--------------------------------------
             transmit start and
             wait for transmission end
             --------------------------------------*/
            
            do
            {                               /* wait for transmission end    */
                
                status = R_IIC00_check_comstate(); /* get IIC status          */
                
            }while( IIC_USING == ( status & IIC_STS_MASK ) );
            
            /*
             release IIC  bus
             */
            R_IIC00_StopCondition();          /* issue stop condition         */
            
        }
        else
        {
            /* do nothing */
        }
        
        return (status);
        
    }

    MD_STATUS put_data_IIC00( uint8_t s_addr, uint8_t buffer1, uint8_t buffer2)
    {

        MD_STATUS status;
        
        g_write_data[0] = buffer1;         /* set data1        */
        g_write_data[1] = buffer2;         /* set data2        */
        
        /*--------------------------------------
         start transmission
         --------------------------------------*/
        
        status = R_IIC00_Master_Send(s_addr, (uint8_t *__near)g_write_data, 2);
        
        if( IIC_SUCCESS == status )         /* check start successfully     */
        {
            
            /*--------------------------------------
             transmit start and
             wait for transmission end
             --------------------------------------*/
            
            do
            {                               /* wait for transmission end    */
                
                status = R_IIC00_check_comstate(); /* get IIC status          */
                
            }while( IIC_USING == ( status & IIC_STS_MASK ) );
            
            /*
             release IIC  bus
             */
            R_IIC00_StopCondition();          /* issue stop condition         */
            
        }
        else
        {
            /* do nothing */
        }
        
        return (status);
        
    }

    MD_STATUS read_byte_IIC00( uint8_t s_addr, uint8_t *const buffer1 )
    {

        MD_STATUS status;

        //g_write_data[0] = buffer2;           /* set register address         */

    /*--------------------------------------
        transmit register address
    --------------------------------------*/

        //status = R_IIC00_Master_Send(s_addr, (uint8_t *__near)g_write_data, 1);

        //if( IIC_SUCCESS == status )         /* check start successfully     */
        //{

    /*--------------------------------------
        wait for transmission end
    --------------------------------------*/

            //do
            //{

                //status = R_IIC00_check_comstate(); /* get IIC status  */

            //}while( IIC_USING == ( status & IIC_STS_MASK ) );

    /*--------------------------------------
       transmission end
    --------------------------------------*/

            //if ( IIC_SUCCESS == status )    /* check result         */
            //{

    /*--------------------------------------
       start IIC receiving
    --------------------------------------*/

                status = R_IIC00_Master_Receive(s_addr, (uint8_t * __near)buffer1, 1);

                if( status == 0)            /* check start successfully     */
                {

    /*--------------------------------------
        wait for receive end
    --------------------------------------*/

                    do
                    {
                        status = R_IIC00_check_comstate();

                    }while( IIC_USING == ( status & IIC_STS_MASK ) );
                }
                else
                {
                    /* do nothing */
                }

            //}
            //else
            //{
                /* do nothing */
            //}

        //}

        R_IIC00_StopCondition();              /* issue stop condition     */

        return (status);

    }

  • (追加) 読み込みも[Shift F6],そして[F6]をしないと正しく読み込みできません.

  • 画像を添付します.lcd_sii_goto1, lcd_sii_puts1はデバッグのための液晶ディスプレイ表示です.

  • チョコ様

    書き込みは正常のようです.読み込みが問題です.

    同じアドレスの読み込みを添付画面の「run the program after the cpu reset」ボタンをクリックすと指定していないアドレスのデータが読み込まれますが,もう一度このボタンを押すと正しく読み込みます.

    読み込みには,

     put_data_IIC00(i2c_adr, adr_high, adr_low);
     read_byte_IIC00(i2c_adr, &data);

    の関数を使用していますが,アドレスを指定するput_data_IIC00が動作不安定です.あらためて,EEPROMのrandom readを見ると,STOPが最後に出ていますが,put_data_IIC00はStop conditionを出しています.read_byte_IIC00もStop conditionを出しています.

  • 画面添付が不足していました.「run the program after the cpu reset」ボタンです.

  • read_byte_IIC00を次のように変更しましたが,状況は同じです.

    MD_STATUS read_byte_IIC00( uint8_t s_addr, uint16_t buffer1, uint8_t *const buffer2 )
    {

        MD_STATUS status;
        uint8_t work1, work2;
        work1 = (uint8_t) (buffer1 << 8);
        work2 = (uint8_t) (buffer1 & 0xFF);
       
        g_write_data[0] = work1;
        g_write_data[1] = work2;           /* set register address         */

    /*--------------------------------------
        transmit register address
    --------------------------------------*/

        status = R_IIC00_Master_Send(s_addr, (uint8_t *__near)g_write_data, 2);

        if( IIC_SUCCESS == status )         /* check start successfully     */
        {

    /*--------------------------------------
        wait for transmission end
    --------------------------------------*/

            do
            {

                status = R_IIC00_check_comstate(); /* get IIC status  */

            }while( IIC_USING == ( status & IIC_STS_MASK ) );

    /*--------------------------------------
       transmission end
    --------------------------------------*/

            if ( IIC_SUCCESS == status )    /* check result         */
            {

    /*--------------------------------------
       start IIC receiving
    --------------------------------------*/

                status = R_IIC00_Master_Receive(s_addr, (uint8_t * __near)buffer2, 1);

                if( status == 0)            /* check start successfully     */
                {

    /*--------------------------------------
        wait for receive end
    --------------------------------------*/

                    do
                    {
                        status = R_IIC00_check_comstate();

                    }while( IIC_USING == ( status & IIC_STS_MASK ) );
                }
                else
                {
                    /* do nothing */
                }

            }
            else
            {
                /* do nothing */
            }

        }

        R_IIC00_StopCondition();              /* issue stop condition     */

        return (status);

    }
  • チョコです。

    「かふぇルネのIICサンプルプログラム」とはどれのことでしょうか。いくつもプログラムが存在し、簡易IICのライブラリはステータス関係を何回か変更しているので、そこらを確定しないと先に進められません。

    「IIC通信のマスタ側(RL78/G13の簡易IIC版)改 2C」のことであれば、制御対象はスレーブのRL78に準備されたRAMを対象にしているので、シリアルEEPROMとは異なります。また、構造と関数名がかなり変わっていたり、関数の引数がポインタだったり、実体渡しだったりして混乱しまっているので、プロジェクト全体の情報がないとコメントできません。す。

    RL78/G13の簡易IICを使用したアプリケーションノートがあるので、そちらを参照される方がいいような気がします。

    renesasのトップページで"r01an2828"で険悪すると見つかります。このアプリケーションノートのサンプルコードは何種類のEEPROMに対応しているようです。

    以上

  • チョコ様

    ご指導ありがとうございます.

    調べたら私が使用しているものは,version 1.10です.別なスレッドでCCRL2CがUpされていますが,EEPROM対応ではないとのこと了解いたしました.なお,速度は400KbpsでPullupは,SDA,SCLとも4.2Kohmです(5V).

    r01an2828を調べてみます.