RL78 UART

R5F1006でUART0とUART1を2400bpsで通信を行い

UART0で受信したデータを編集してUART1で送信

UART1で受信したデータを編集してUART0で送信というプログラムを作成しています。

コード生成ツールのボーレートの設定に2400がでてきませんが、直接2400を入力して

コード生成をしたら設定されるのでしょうか?

(現状は9600bpsで確認を行っています)

UART0側をPC、UART1側を周辺機器に接続していて、UART0で1度は受信割込みが入り

受信できるのですが、プログラムを再起動しないと続けてPCからのデータを受信できません。

何か処理が必要でしょうか?

  • チョコです。

    >コード生成ツールのボーレートの設定に2400がでてきませんが、直接2400を入力して

    >コード生成をしたら設定されるのでしょうか?

    はい、可能です。

    >UART0側をPC、UART1側を周辺機器に接続していて、UART0で1度は受信割込みが入り

    >受信できるのですが、プログラムを再起動しないと続けてPCからのデータを受信できません。

    >何か処理が必要でしょうか?

    UART0の受信割り込みはどのように処理されているのでしょうか。受信したデータは読み出していますか?

    割り込みは、割り込みを受け付けてベクターに分岐(受信データを読み出してから割り込みから戻る)するか、割り込み要求をポーリング(SRIF0ビットが1になるのを待ち、セットされたらSRIF0ビットをクリアして受信データを読み出すことで、次のデータ受信が可能になります。

    ひとまずはかふぇルネの画面の上の方にある「サンプルプログラム等」に参考になる内容があります。

    https://japan.renesasrulz.com/cafe_rene/m/sample_program

    RL78の割り込みについては、「サンプルプログラム等」の「RL78割り込みについて」に開設があります。

    https://japan.renesasrulz.com/cafe_rene/m/sample_program/313

    また、RL78のUARTについては、「RL78でのUARTの使い方(1)」も参考にしてみてください。

    https://japan.renesasrulz.com/cafe_rene/m/sample_program/304

    「RL78での調歩同期通信について」も参考にしてください。

    https://japan.renesasrulz.com/cafe_rene/m/sample_program/302

    UARTの制御プログラムは「RL78のUART 制御のプログラム例1」も参考になるかもしれません。

    https://japan.renesasrulz.com/cafe_rene/m/sample_program/305

    以上

  • チョコさん早々の回答ありがとうございます。

    参考にさせて頂きます。

    R5F1006でUART0を9600bps UART1を2400bpsとボーレートを分ける事は可能でしょうか?

    R5F1006の場合UART0とUART1のクロックソースが1種類なので、無理なような気がしますが・・・

  • チョコです。

    >R5F1006でUART0を9600bps UART1を2400bpsとボーレートを分ける事は可能でしょうか?

    可能です。

    >R5F1006の場合UART0とUART1のクロックソースが1種類なので、無理なような気がしますが・・・

    SAUには1ユニット当たり2つのプリスケーラがあり、各ユニットはプリスケーラにより2種類のクロックソース(CKm0とCKm1)が選択できます。(RL78では、2400と9600では同じクロックソースでもSDRレジスタの上位7bittの設定で可能です。2400なら104分周9600なら26分周になるので、十分使えますが。)

    なお、コード生成では、各チャネルの設定は送信用と受信用で分かれています。ボーレートを変更するときは、送信用だけでなく、受信用も2400に変更することを忘れないでください。

  • チョコさん早々の回答ありがとうございます。

    教えて頂いた参考を元にプロジェクトを作り直して、連続受信できるようになりました。

    コード生成ツールでUART0,UART1ともボーレートを2400を入力してコードを生成して

    UART0側はPCアプリで2400bpsで接続して、送受信ができていて波形も確認すると

    2400bpsになっていますが、UART1の方が波形を確認すると9600bpsになっていて、周辺機器

    との接続ができない状態です。

    周辺機器はCOSELのPCA600F-24-Tという物で、2400bps固定の為2400bpsで通信する必要があります。

    初歩的な事をお聞きします。

    ボーレート調整はどのレジスタを確認したらいいでしょうか。

  • チョコさん

    コード生成ツールのUART1の方に誤りがあると思われます。

    R_UART0_CreateとR_UART1_Createのレジスタ設定を見比べたのですが、

    UART0側のSDR00とSDR01は0xCE00という値になっているのに

    UART1側はSDR02が0x3200でSDR03が0xCE00になっていました。

    SDR02を0xCE00に修正したところ、2400bpsの波形が確認できました。

    接続する機器が偶数パリティなので、コード生成で偶数パリティを選択したのですが、

    SDR02の方がパリティ無し、SDR03が偶数パリティで生成されていました。

    個の場合SDR02も偶数パリティに設定される必要があるかと思います。

    その他生成ツールで不具合がある箇所はあるのでしょうか。

  • チョコです。

    >ボーレート調整はどのレジスタを確認したらいいでしょうか。

    ボーレートはSPS0レジスタでプリスケーラの設定がおこなわれ、UART0はSMR00(送信)とSMR01(受信)のbit15でCK00かCK01を選択し、UART1はSMR02(送信)とSMR03(受信)のbit15でCK00かCK01を選択しています。

    さらにSDR0nレジスタの上位7bitで動作クロック(プリスケーラのシュルよく)からボーレートを指定しています。。

    コード生成で、32MHzのシステムクロック時に、UAR0とUART1をともに2400に設定(合計で4か所)したところ、CK00もCK01も2^6分周になって、64分周になっていました(500kHz)。その上で、R_UART0_Create関数でSMR00及びSMR01レジスタのbit15は0なのでCK00を選択、その上で、SDR00及びSDR01レジスタの値は0xCE00なので、SDRでの分周は104分周になります。

    UART0もUART 1も同じレジスタ設定は同じになっています。

  • チョコです。

    行き違いになり、一部解決されたようです。

    >接続する機器が偶数パリティなので、コード生成で偶数パリティを選択したのですが、

    >SDR02の方がパリティ無し、SDR03が偶数パリティで生成されていました。

    >個の場合SDR02も偶数パリティに設定される必要があるかと思います。

    >その他生成ツールで不具合がある箇所はあるのでしょうか。

    コード生成はUART0及びUART1で送信側と受信側の両方を設定しないといけません。

    こちらで(パリティなしで)設定したときのレジスタの設定値を示します。R5F1006の環境はないので、シミュレータでの確認画面を下に示します。初期設定だけでmain関数の頭でブレークした状態の画面です。

    つまり、ツールの不具合ではなく、設定の問題(設定もれ)です。

    以上

  • R5F1006A_UART.zip

    チョコです。

    >UART1側はSDR02が0x3200でSDR03が0xCE00になっていました。

    SDR02の0x3200は何かおかしい値ですね。通常のコード生成では、できるだけSDR側の値を大きくするような設定になるはずなので、ここだけを直してボーレートが正しくなるのは、おかしいですね。

    おかしな結果が出るか色々と試してみたのですが、おかしな設定らしいものを検証できませんでした。

    これは、いくらやっても駄目だと判断し、わかさんのやりたい設定を行ったプロジェクトを添付しますので、こちらを参照ください。単に初期設定だけで、通信の起動は行っていません。

    以上

  • チョコさま

    色々ありがとうございます。

    ボーレートの件は解決しました。

    R5F1006でUART0で受信を行って、基板番号とUART0から受信した基板番号が一致したら、データ処理をして

    UART1から送信、一致しなかったら何もせず受信待ちというプログラムにしたいのですが、

    一致しなかった時の文(237~241行目)を実行するとその後UART0から受信できなくなります。

    何が原因でしょうか?

    文法が間違っているのでしょうか?

    ソースコードを添付します。

    7002.UART_PCB4.zip

  • チョコです。

    大きな処理の流れは分からないので、気が付いた部分を記述します。

    195~198行目でUART0と1の受信を起動していますが、UART0受信完了時にUART1は受信完了していない可能性はないでしょうか。(38400bpsで18文字よりは2400で5文字の方が単純な通信時間の比較では時間がかかりますが。)

    228行目のSRMK1 = 1U;は231行目のUART1受信の割り込み処理を妨害します。

    232行目、240行目、279行目、313行目のHALT();は1文字の通信完了で解除されますが、それで問題はないですか。

  • チョコです。

    少し、追加しておます。

    >一致しなかった時の文(237~241行目)を実行するとその後UART0から受信できなくなります。

    >何が原因でしょうか?

    前回のリプライに書いたように、UART1の受信が完了していない状態でここまで来て、完了していないR_UART1_Receiveが新たなR_UART1_Receiveで上書きされているのではないかと考えられます。

    UART0とUART1の通信の状態を確認することをお勧めします。

    ここらは文法云々ではなく、通信プロトコルの理解の問題と、コード生成のAPIの動作をよく理解していないことが原因ではないかと思います。

  • わか さん、こんにちは。NoMaYです。

    チョコさんのアドバイスは理解出来ましたでしょうか?

    > 大きな処理の流れは分からないので、気が付いた部分を記述します。
    ...途中省略...
    > ここらは文法云々ではなく、通信プロトコルの理解の問題と、コード生成のAPIの動作をよく理解していないことが原因ではないかと思います。

    わかさんのソースを見た時の第一印象は、HALT()を使っているのは省電力化の為ではなく、コード生成のAPIの動作を理解出来なくて(これは「初心者あるある」なのですが)、HALT()を使ったら兎に角動いたのでそういうものだと勘違いしてソースを書き続けているのではないかなぁ、という気がしたのですが、、、

    前のスレッド:

    RL78でブレークポイントを外すと動作しない
    japan.renesasrulz.com/cafe_rene/f/forum18/6947/rl78
     

  • チョコです。

    その後、何もコメントがないようなので、追加でコメントします。

    >R5F1006でUART0で受信を行って、基板番号とUART0から受信した基板番号が一致したら、データ処理をして
    >UART1から送信、一致しなかったら何もせず受信待ちというプログラムにしたいのですが

    なぜ、プログラムがそのようになっていないのでしょうか。(一致した場合も一致しなかった場合もR_UART1_Receive()を再起動しているのでしょうか。)

    それと、通信の制御の基本ですが、単純に送信や受信を起動をしているのは、気になります。受信はwhile(1U)の前でR_UART0_ReceiveとR_UART1_Receiveを呼び出しているのでいいのですが、送信の方は、フラグの初期値が0になっているのは問題で、初期値は1にしておいて、フラグが1なら次のデータの送信が可能、0なら送信中なので次の送信はできないとすべきです。(もちろんwhile(1U)の中では、受信のフラグが1のときに受信データを処理して、次の受信を起動したときにフラグを0(通信中)にすべきです。

    とにかく、どの場合に何をやるかを明確にすべきです。その上で、新たな通信の起動が可能かどうかをきちんとチェックすべきです。

    調歩同期通信の受信に関しては、いつ通信されてくるかは分かりません。(だから、調歩同期通信を非同期通信と言いますが)このことをきちんと意識してプログラムを作成すべきです。

    以上

  • チョコです。

    わかさん、その後どうなっていますか。

    念のために、コード生成のR_UART1_Receive()関数について説明しておきます。

    このAPI関数は以下のようなプログラムになっています。

    MD_STATUS R_UART1_Receive(uint8_t * const rx_buf, uint16_t rx_num)
    {
        MD_STATUS status = MD_OK;

        if (rx_num < 1U)
        {
            status = MD_ARGERROR;
        }
        else
        {
            g_uart1_rx_count = 0U;
            g_uart1_rx_length = rx_num;
            gp_uart1_rx_address = rx_buf;
        }

        return (status);
    }

    受信するデータ数が0ならば、MD_ARGERRORを戻すようになっています。データ数が1以上ならば、引数を内部の作業用変数(g_uart1_rx_lengthやgp_uart1_rx_address)にコピーし、受信データ数をカウントする変数(g_uart1_rx_count)を0クリアしています。

    これらの処理は、すでに受信処理が動作中かどうかとは無関係に行われます。これが、問題なのです。ここらは使う方がきちんとケアするようにする必要がありますが、マニュアルに何も書かれていません。(マニュアルに何も書かれていないのが一番の問題でしょう。)

    とにかく、処理を完了する前に次の処理を起動するとこれらの変数が新しいデータに書き換わってしまうので、いつまでたっても、処理が完了しなくなることを理解しておいてください。

    以上