電流・電圧測定デバイスであるINA233を用いて電圧値を測定し,測定値を簡易IIC通信でRX231に送るプログラムを作成しておりますが上手くいきません.
RX231シリーズ R5F52316ADFM
ROM:256Kbyte RAM 32Kbyte 外部発振20MHzを使用しています.
コード生成はSCI12を簡易IICバスに設定し,生成しました.
void main(void){ R_MAIN_UserInit(); /* Start user code. Do not edit comment generated here */ { uint8_t adr =0 ;//7bit address uint8_t dir =0 ;//0:Write 1:Read uint8_t tx_buf[255] = {0};//send data uint8_t rx_buf[255] = {0};//receive data while(1){ adr = 0x41; dir = 0x00; adr = (adr<<1) | (dir & 0x00); tx_buf[0] = 0x88; //READ_VIN PMBusコード ina233 tx_buf[1] = 0x89; //READ_IN PMBusコード ina233 //PMBusコマンド ina233に送信 R_SCI12_Create(); R_SCI12_Start(); R_SCI12_IIC_Master_Send(adr,&tx_buf[0],3); R_SCI12_Stop(); adr = 0x41; dir = 0x01; adr = (adr<<1) | (dir & 0x00); //ina233からデータ取得 R_SCI12_Start(); R_SCI12_IIC_Master_Receive(adr,rx_buf,3); R_SCI12_Stop(); } } /* End user code. Do not edit comment generated here */}
CS+の設定等もよく分からないのでその辺りも教えていただけるとありがたいです.
初歩的な質問ですいませんが,よろしくお願いいたします.
//INA233のデータシート
www.ti.com/.../ina233.pdf
fiReさん、こんにちは。NoMaYと申します。ソースコードはこれから見るところですが、どのようにうまくいかないのか、もう少し具体的に教えて頂けますか?ズバリ、rx_bufに期待したデータが入っていない、あたりでしょうか?
fiReさん、こんにちは。NoMaYです。少し脱線しますが、確認したいことがあります。今現在、RX231のソフトウェア開発で使われるツールはRXスマートコンフィグレータというものになるのですが、fiReさんが提示されているソースコードはコード生成機能とよばれる機能で生成されたソースになっています。頂いている文面から察するに、CS+を使うのは初めて?(RX231というより)RXマイコンを使うのも初めて?のように思われるのですが、どういう経緯で、RXスマートコンフィグレータを使わずにコード生成機能を使われているのですか?私がとっさに思い浮かべたのは、以下の理由かな?と思ったのですが、、、(1) スタータキット(Renesas Starter Kit for RX231)に同梱されていた(?)かなり古い(?)CS+を使用していてコード生成機能しか無かったので?製品ページURLwww.renesas.com/jp/ja/products/software-tools/boards-and-kits/starter-kits/renesas-starter-kit-for-rx231.htmlちなみにRenesas Starter Kit for RX231(B版: Trusted Secure IP搭載)もDVD内のCS+はかなり古いのだろうか、、、(独り言です、、、)www.renesas.com/jp/ja/products/software-tools/boards-and-kits/starter-kits/renesas-starter-kit-for-rx231b.html[訂正] すみません、そういえば、Renesas公式サンプルコードはe2 studio版しかありませんでした。(2) ターゲットボード(Target Board for RX231)向けRenesas公式サンプルコード(この機種だけコード生成機能を使用)をベースにしたので?サンプルコードダウンロードURLwww.renesas.com/jp/ja/software/D6002186.htmlちなみに、コード生成機能で生成されたものかRXスマートコンフィグレータで生成されたものかは、以下のようにAPI関数が若干異なりますので、区別が出来ます。コード生成機能で生成例) R_SCI12_IIC_Master_Send()RXスマートコンフィグレータで生成例) R_Config_SCI12_IIC_Master_Send()
チョコです。
>while(SCI12.SSR.BIT.TDRE == 0){
>R_SCI12_IIC_Master_Send(adr,&tx_buf[0],3);
>}
この処理は間違いです。最初に送信を一度起動して,送信完了を待ちます。
R_SCI12_IIC_Master_Send(adr,&tx_buf[0],3);
while(...){
}
同様に受信についても,最初にR_SCI12_IIC_Master_Receive(adr,rx_buf,3);
で受信を起動してから,受信完了を待ちます。おそらくSSR.RDRFでは,1バイトでも受信したら抜けてしまうので,鈴木さんが提示した資料を参照してください。(送信についても同様。)
細かなことですが,adr = (adr<<1) | (dir & 0x00);の右側の項は常に0なので,無意味です。というか,これ自体が不要では。
以上
fiReさん、こんにちは。NoMaYです。以下のリプライを有難う御座いました。そうでしたか、ルネサスさんのウェブサイトからCS+をダウンロード/インストールしても、RXスマートコンフィグレータがインストールされなかったのですね。そうなると、ここ暫くは(こうやればインストール出来ますよとアドバイスが出来る状態に私がなるまでは(週末調べてみます))、コード生成機能で作業を進めるしかないですね。[追記] あっ、そういば、もう金曜日の夕方ですね、、、> RENESASのHPから統合環境をインストールしてCS+を使っている状態です。> RXスマートコンフィグレータの存在は知りませんでした、、> あとお察しの通りrxマイコンもCS+も今回初めて使っています。多数の別スレッド(RL78ですが)でチョコさんがコード例を提示されているのですが、ルネサスさんのコード生成機能やRXスマートコンフィグレータの通信系のAPI関数仕様は、初心者さんがちょっと使い始めようとする時点ではコツが分からず皆苦労されるようです。(コツといっても実に些細なことで、コードを提示してしまえば直ぐに分かることですが、文章で書くと分かり難い気もします、、、これから私の手元でコード生成機能でソースを生成させてみますので、暫くお待ちください、、、)それとは別に、相手側デバイスのデータシートを見ていて気になったのですが、チョコさんも指摘されているように、以下の処理は不要だと思われます。(これからソースを生成させて確認しますが。) つい最近の別スレッドでの話なのですが、RX版のコード生成機能のAPI関数に渡すスレーブのアドレスは7bitアドレスのようですので、以下でadr=0x41としたら、その下の2行は不要だと思われます。ちなみに、スレーブのアドレスが0x41ということは、相手側デバイスのA1端子=GND&A0端子=VSなのですよね?
adr = 0x41;dir = 0x01;adr = (adr<<1) | (dir & 0x00);
また、同じく、相手側デバイスのデータシートを見ていて気になったのですが、以下のようにPMBus Command Codeを複数指定することは出来ないのではないでしょうか?(データシートを斜め読みしている段階ですので、私が読み漏らしているかもしれませんが、、、)
tx_buf[0] = 0x88; //READ_VIN PMBusコード ina233tx_buf[1] = 0x89; //READ_IN PMBusコード ina233
[関連リンク]RX版のコード生成機能のAPI関数に渡すスレーブのアドレスは7bitアドレスである、という話があった、つい最近の別スレッドのURLです。アドレス部の先頭1bitが送信されない(I2C)japan.renesasrulz.com/cafe_rene/f/forum5/6157/1bit-i2c/34102#34102
fiReさん、こんにちは。NoMaYです。ごめんなさい。ソースを生成させて確認したところ、(RX版の)コード生成機能の簡易I2CのAPI関数に渡すスレーブのアドレスは8ビットのようでした。ですので、(少なくとも)簡易I2Cでは以下の処理が必要そうですね。(ただ、アンドする値は0x00ではなくて0x01の間違いですね。)Send時
adr = 0x41;dir = 0x00;adr = (adr<<1) | (dir & 0x01);
Receive時
adr = 0x41;dir = 0x01;adr = (adr<<1) | (dir & 0x01);
以下、確認した時のSendに関する資料です。(自分自身への備忘録としてでもあります。)RX230グループ、RX231グループ ユーザーズマニュアル ハードウェア編の画面コピーwww.renesas.com/jp/ja/search/keyword-search.html#genre=document&q=r01uh0496r01uh0496jj0120-rx231.pdfr_cg_sci.c
void R_SCI12_IIC_Master_Send(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num){ if (1U > tx_num) { return; } gp_sci12_tx_address = tx_buf; g_sci12_tx_count = tx_num; g_sci12_slave_address = adr; g_sci12_iic_transmit_receive_flag = _80_SCI_IIC_TRANSMISSION; g_sci12_iic_cycle_flag = _80_SCI_IIC_START_CYCLE; /* Disable RXI and ERI interrupt requests */ SCI12.SCR.BIT.RIE = 0U; /* Generate start condition */ R_SCI12_IIC_StartCondition();}
r_cg_sci_user.c
static void r_sci12_transmitend_interrupt(void){ if (_80_SCI_IIC_START_CYCLE == g_sci12_iic_cycle_flag) { SCI12.SIMR3.BIT.IICSTIF = 0U; SCI12.SIMR3.BIT.IICSCLS = 0U; SCI12.SIMR3.BIT.IICSDAS = 0U; SCI12.TDR = g_sci12_slave_address; } else if (_00_SCI_IIC_STOP_CYCLE == g_sci12_iic_cycle_flag) { SCI12.SIMR3.BIT.IICSTIF = 0U; SCI12.SIMR3.BYTE |= _30_SCI_SSDA_HIGH_IMPEDANCE | _C0_SCI_SSCL_HIGH_IMPEDANCE; if (_80_SCI_IIC_TRANSMISSION == g_sci12_iic_transmit_receive_flag) { r_sci12_callback_transmitend(); } if (_00_SCI_IIC_RECEPTION == g_sci12_iic_transmit_receive_flag) { r_sci12_callback_receiveend(); } }}
fiReさん、こんにちは。NoMaYです。チョコさんが仰っていたこと(以下)をコードにしてr_cg_sci_user.cのユーザ記述部に書くと以下のようになります。これを使ってr_cg_main.cを以下のように書き換えたらどうなりますでしょうか?(参考用に当方で試しに書き換えたプロジェクトのファイル一式を添付します。ただ、過去のプロジェクトのファイルを流用したのでresetprg.cが最新版では無かったりするので、参考にするぐらいにして下さい。また、相手側デバイスを持ち合わせていません(実はI2C全般で持ち合わせていません)ので、動作は未確認です。すみません。)「SCI12の割り込み処理のコードを参照して,指定したデータ数の転送が完了したところで,何かコールバック処理をやっていると思うので,そこで通信完了フラグをセットして,そのフラグを確認するような通信待ちを行ってみてください。」プロジェクトのファイル一式issue_20200214.zip 293KB今回、送信完了/受信完了を待つ送信関数名/受信関数名の末尾に _UWT を付けてみました。(unlimited wait timeの意。また、先頭を R_ ではなくて U_ にしてあります。ちなみに、STM32CubeMXでは送信完了/受信完了を待たない関数の名前の末尾に _IT を付けるようでしたので、逆向きに(?)真似てみました。) なお、スレーブアドレスは7ビットアドレスを受け取るようにしました。cg_src/r_cg_sci_user.c
/******************************************************************************Global variables and functions******************************************************************************/extern uint8_t g_sci12_iic_transmit_receive_flag; /* SCI12 transmit receive flag for I2C */extern uint8_t g_sci12_iic_cycle_flag; /* SCI12 start stop flag for I2C */extern uint8_t g_sci12_slave_address; /* SCI12 target slave address */extern uint8_t * gp_sci12_tx_address; /* SCI12 send buffer address */extern uint16_t g_sci12_tx_count; /* SCI12 send data number */extern uint8_t * gp_sci12_rx_address; /* SCI12 receive buffer address */extern uint16_t g_sci12_rx_count; /* SCI12 receive data number */extern uint16_t g_sci12_rx_length; /* SCI12 receive data length *//* Start user code for global. Do not edit comment generated here */volatile uint8_t g_sci12_tx_ready_flag; /* SCI12 send end flag */volatile uint8_t g_sci12_rx_ready_flag; /* SCI12 receive end flag *//* End user code. Do not edit comment generated here */
static void r_sci12_callback_transmitend(void){ /* Start user code. Do not edit comment generated here */ g_sci12_tx_ready_flag = 1; /* End user code. Do not edit comment generated here */}
static void r_sci12_callback_receiveend(void){ /* Start user code. Do not edit comment generated here */ g_sci12_rx_ready_flag = 1; /* End user code. Do not edit comment generated here */}
/* Start user code for adding. Do not edit comment generated here *//******************************************************************************* Function Name: U_SCI12_IIC_Master_Send* Description : This function sends IIC12 data to slave device. (unlimited wait time)* Arguments : same as R_SCI12_IIC_Master_Send except for adr* adr -* slave device '7-bit' address (Not '8-bit' address)* Return Value : same as R_SCI12_IIC_Master_Send******************************************************************************/void U_SCI12_IIC_Master_Send_UWT(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num){ R_SCI12_IIC_Master_Send( (uint8_t)(adr << 1), tx_buf, tx_num ); do{}while (g_sci12_tx_ready_flag != 1); g_sci12_tx_ready_flag = 0;}/******************************************************************************* Function Name: R_SCI12_IIC_Master_Receive* Description : This function receives IIC12 data from slave device. (unlimited wait time)* Arguments : same as R_SCI12_IIC_Master_Receive except for adr* adr -* slave device '7-bit' address (Not '8-bit' address)* Return Value : same as R_SCI12_IIC_Master_Receive******************************************************************************/void U_SCI12_IIC_Master_Receive_UWT(uint8_t adr, uint8_t * const rx_buf, uint16_t rx_num){ R_SCI12_IIC_Master_Send( (uint8_t)((adr << 1) | 1), rx_buf, rx_num ); do{}while (g_sci12_rx_ready_flag != 1); g_sci12_rx_ready_flag = 0;}/* End user code. Do not edit comment generated here */
cg_src/r_cg_sci.h
/* Start user code for function. Do not edit comment generated here */void U_SCI12_IIC_Master_Send_UWT(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num);void U_SCI12_IIC_Master_Receive_UWT(uint8_t adr, uint8_t * const rx_buf, uint16_t rx_num);/* End user code. Do not edit comment generated here */
cg_src/r_cg_main.c
void main(void){ R_MAIN_UserInit(); /* Start user code. Do not edit comment generated here */ { uint8_t adr = 0;//7bit address uint8_t tx_buf[255] = {0};//send data uint8_t rx_buf[255] = {0};//receive data R_SCI12_Start(); while(1) { adr = 0x41; tx_buf[0] = 0xE0; //TI_MFR_ID PMBusコード ina233 //PMBusコマンド ina233に送信 U_SCI12_IIC_Master_Send_UWT( adr, tx_buf, 1 ); //ina233からデータ取得 U_SCI12_IIC_Master_Receive_UWT( adr, rx_buf, 2 ); //デバッグ時にブレークポイントやアクションイベントを設定する箇所 //ここまで来たら rx_buf[0] = 'T', rx_buf[1] = 'I' となっている筈 nop(); } } /* End user code. Do not edit comment generated here */}
以下、作成した時の資料です。(自分自身への備忘録としてでもあります。)INA233データシートの画面コピーwww.ti.com/jp/lit/ds/symlink/ina233.pdfCS+のコード生成機能の設定画面CS+のコード生成機能のヘルプのSCIのAPIの使用例の画面コピー