初めまして。恐らく初歩的な質問となると思うのですが、よろしければご教授お願い致します。
使用している総合開発環境はCS+forCCです。
RL78/G1D R5F11AGJ の簡易i2cを使用して6軸加速度センサLSM6DS3との通信を実現したいと思っています。
今まではArduinoを使用していたのですが、諸事情によりRL78/G1Dに変更することになりました。
ハードウェアマニュアルやサンプルプログラムを見ながら試行錯誤しているのですが、いまいち要領を得ません。
シリアルアレイユニットのIIC00をコード生成後、加速度センサの値を読みたい時のおおまかな流れは以下の様な理解で良いのでしょうか?
/*********************************************************************************************/
R_SAU0_Create()/*シリアルアレイユニット0、IIC00初期設定*/
R_IIC00_Master_Send(uint8_t slave_address,uint8_t register_address,1)/*スレーブアドレス、アクセスするレジスタアドレス、バッファーサイズを指定*/
/***r_iic00_interrupt()により転送完了割り込みが発生,アドレスフィールド送信***/
R_IIC00_Master_Receive(uint8_t slave_address, (uint8_t *)data_address, buffer_size) /*data_addressはスレーブから受け取ったデータを格納*/
/***r_iic00_interrupt()により転送完了割り込みが発生,data_addressに指定したレジスタアドレスの値をバッファーサイズ分格納***/
割り込み処理についてよく理解ができておらず、その辺りの流れに頭を悩ませております。
この様なちゃんとした?マイコンを扱うのが初めてで、右も左もわからない状態なのですが是非よろしくお願いいたします。
以下にコード生成されたMaster_Send,Master_Receive,r_iic00_interruptのソースを貼ります。
/************************************************************************************************************************ Function Name: R_IIC00_Master_Send* Description : This function starts transferring data for IIC00 in master mode.* Arguments : adr -* set address for select slave* tx_buf -* transfer buffer pointer* tx_num -* buffer size* Return Value : None***********************************************************************************************************************/void R_IIC00_Master_Send(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num){ g_iic00_master_status_flag = _00_SAU_IIC_MASTER_FLAG_CLEAR; /* clear IIC00 master status flag */ adr &= 0xFEU; /* send mode */ g_iic00_master_status_flag = _01_SAU_IIC_SEND_FLAG; /* set master status flag */ SCR00 &= ~_C000_SAU_RECEPTION_TRANSMISSION; SCR00 |= _8000_SAU_TRANSMISSION; /* Set paramater */ g_iic00_tx_count = tx_num; gp_iic00_tx_address = tx_buf; /* Start condition */ R_IIC00_StartCondition(); IICIF00 = 0U; /* clear INTIIC00 interrupt flag */ IICMK00 = 0U; /* enable INTIIC00 */ SIO00 = adr;}/************************************************************************************************************************ Function Name: R_IIC00_Master_Receive* Description : This function starts receiving data for IIC00 in master mode.* Arguments : adr -* set address for select slave* rx_buf -* receive buffer pointer* rx_num -* buffer size* Return Value : None***********************************************************************************************************************/void R_IIC00_Master_Receive(uint8_t adr, uint8_t * const rx_buf, uint16_t rx_num){ g_iic00_master_status_flag = _00_SAU_IIC_MASTER_FLAG_CLEAR; /* clear master status flag */ adr |= 0x01U; /* receive mode */ g_iic00_master_status_flag = _02_SAU_IIC_RECEIVE_FLAG; /* set master status flag */ SCR00 &= ~_C000_SAU_RECEPTION_TRANSMISSION; SCR00 |= _8000_SAU_TRANSMISSION; /* Set parameter */ g_iic00_rx_length = rx_num; g_iic00_rx_count = 0U; gp_iic00_rx_address = rx_buf; /* Start condition */ R_IIC00_StartCondition(); IICIF00 = 0U; /* clear INTIIC00 interrupt flag */ IICMK00 = 0U; /* enable INTIIC00 */ SIO00 = adr;}
/************************************************************************************************************************ Function Name: r_iic00_interrupt* Description : None* Arguments : None* Return Value : None***********************************************************************************************************************/static void __near r_iic00_interrupt(void){ if (((SSR00 & _0002_SAU_PARITY_ERROR) == 0x0002U) && (g_iic00_tx_count != 0U)) { r_iic00_callback_master_error(MD_NACK); } else if(((SSR00 & _0001_SAU_OVERRUN_ERROR) == 0x0001U) && (g_iic00_tx_count != 0U)) { r_iic00_callback_master_error(MD_OVERRUN); } else { /* Control for master send */ if ((g_iic00_master_status_flag & _01_SAU_IIC_SEND_FLAG) == 1U) { if (g_iic00_tx_count > 0U) { SIO00 = *gp_iic00_tx_address; gp_iic00_tx_address++; g_iic00_tx_count--; } else { R_IIC00_StopCondition(); r_iic00_callback_master_sendend(); } } /* Control for master receive */ else { if ((g_iic00_master_status_flag & _04_SAU_IIC_SENDED_ADDRESS_FLAG) == 0U) { ST0 |= _0001_SAU_CH0_STOP_TRG_ON; SCR00 &= ~_C000_SAU_RECEPTION_TRANSMISSION; SCR00 |= _4000_SAU_RECEPTION; SS0 |= _0001_SAU_CH0_START_TRG_ON; g_iic00_master_status_flag |= _04_SAU_IIC_SENDED_ADDRESS_FLAG; if (g_iic00_rx_length == 1U) { SOE0 &= ~_0001_SAU_CH0_OUTPUT_ENABLE; /* disable IIC00 out */ } SIO00 = 0xFFU; } else { if (g_iic00_rx_count < g_iic00_rx_length) { *gp_iic00_rx_address = SIO00; gp_iic00_rx_address++; g_iic00_rx_count++; if (g_iic00_rx_count == (g_iic00_rx_length - 1U)) { SOE0 &= ~_0001_SAU_CH0_OUTPUT_ENABLE; /* disable IIC00 out */ SIO00 = 0xFFU; } else if (g_iic00_rx_count == g_iic00_rx_length) { R_IIC00_StopCondition(); r_iic00_callback_master_receiveend(); } else { SIO00 = 0xFFU; } } } } }}
チョコです。
>(1)簡易IICでは、1バイト送信後に5usのインターバルが必要という記事がありましたが、
簡易IICそのものにそのような制限事項はありません。問題はスレーブ側での処理速度です。RL78の簡易IICでは,スレーブ側からウエイトを掛けることができないので,その分をマスタ側でケアしておく必要があります。そのためのものが,5usのインターバルです。これは,スレーブがマイコンのようにソフトウェアで処理している場合には,すぐには次の通信が始められないことがあります。ここらへの対応です。
汎用的なAPIとする場合には考慮しておきべきものです。コード生成ではここらの考慮が不足しています(と考えています)。
>このスレッドでは、そのことに言及はなく
このスレッドで使っている6軸加速度センサLSM6DS3のような専用のデバイスでは,IICの制御はハードウェアで実現していると考えられるので,ウエイトは必要ありません。(したがって,言及していません。)
>自前フラグをセットするしないにかかわらず、実際には送信はされていると思います。
問題は”R_IIC00_Master_Receive関数"や”R_IIC00_Master_Send関数"を呼び出して,そこから戻ってきた段階では通信は始まったばかりで完了していないということです。そのために通信が実際に完了するまで待つ必要があるということです。
(今はどうなっているか確認していませんが,コード生成のAPIのマニュアルには,あたかも「関数から戻ってきたら通信が完了している」ような記述がありました。)
>このMaster_Sendの実行でデータ送信は行われるのでしょうか。
送信そのものは始まります。
>レジスタをセットしトリガを与えないと送信できないという記事もあったと思います。
それは,RL78でハードウエアを直接制御する場合のことだと思います。通信関係は,I/Fを起動しても,送信データまたはダミーデータを書きかまないと通信は始まらないの意味です。
>簡易IICによるデータ送信の方法について、まとまった情報を得たいのですが、RL78について、どこで見ればよいのでしょうか?ご教示よろしくお願いします。
かふぇルネのTOPページの上の方に「サンプルプログラム等」とあるので,そこをクリックしてください。(「サンプルプログラム等」が見えない場合には右の「More」をクリックすれば出てきます。)
サンプルプログラム等に移動したら,少し下の方に投稿リストのエクセルファイルがダウンロードできるスレッドがあるので,エクセルファイルをダウンロードしてください。
このリストの上の方にIIC関係の情報があります。リンクが張ってあるので,それらを参照してください。
チョコ様
早速のご回答有難うございました。
また、サンプルプログラムの入手方法についても、ただいまExcelファイルをDLし、17/12/18のチョコ様投稿の「IIC通信のマスタ側(RL78/G13の簡易IIC版)改 2C」をDLしコードを研究したいと思います。このDLしたプロジェクトのコード生成プロパティを添付しますが、「API関数出力制御」の"初期化関数のみ出力"が指定してありました。他のサンプルコードでも、同様に"初期化関数のみ出力"の指定が指示されてたものがありました。もう一つの選択肢である"設定に合わせすべて出力する"の違いが説明を読んでも具体的に分かりません。例えば、簡易IICで使用する"R_IIC00_Master_Send"関数については、コード生成されたものを使用すべきだと考えます。サンプルコードもこのコード生成された関数の仕様を前提に作成すべきだと思います。そうしないと、応用が利かないと思うのですが。。。あるいはコード生成されたコードは安定的に動作しないものでしょうか?
今後のプログラム作成のときのために、よろしくご指導お願いします。