シリアル通信の方法

はじめまして。以前にRX231を使ってPWM波形を出力する方法で質問させていただいたものです。

今度はシリアル通信(Uart)に挑戦しようと思って、まずは1バイトの文字を送ってその文字を受信する、

その次に任意のバイト数の文字列を送信し、それに応じてマイコンを動かすということを行いたいと考えているのですが、

1バイトの送受信が出来ずつまづいています。スマートコンフィグレータを使って生成されたコードを使って書いてますが、

ハードウェアマニュアルを読んでも具体的な書き方が分かりません。

下記どなたかご教授頂けないでしょうか?

何卒よろしくお願いします。

 

 

①自動生成された下記の関数の意味と使い分け

※SCI5を使用 

<Config_SCI5.c>

MD_STATUS R_Config_SCI5_Serial_Receive(uint8_t * const rx_buf, uint16_t rx_num)→受信データの処理関数?

MD_STATUS R_Config_SCI5_Serial_Send(uint8_t * const tx_buf, uint16_t tx_num)→送信データの処理関数?

<Config_SCI5_user.c>

static void r_Config_SCI5_receive_interrupt(void)→受信割り込み時の処理関数?

static void r_Config_SCI5_receiveerror_interrupt(void)→受信割り込みエラー時の処理関数?

static void r_Config_SCI5_transmit_interrupt(void)→送信割り込み時の処理関数?

static void r_Config_SCI5_transmitend_interrupt(void)→送信割り込み完了時?の処理関数?(上記の関数と何が違う?)

static void r_Config_SCI5_callback_transmitend(void)→送信完了時の何らかの関数?

static void r_Config_SCI5_callback_receiveend(void)→受信完了時の何らかの関数?

static void r_Config_SCI5_callback_receiveerror(void)→受信エラー時の何らかの関数?

 

②下記のようにプログラムを書きましたが、Teraterm上から送った1バイトの文字が無数に帰ってきます。

一旦受信したデータをバッファに置いて、送信する、という趣旨の書き方をしたいのですが、どのように

書けばよいのかも分かりません。

 

#define BUFFERSIZE 32

static int RxBuffer [BUFFERSIZE ];

void main(void)

{

      //InitとSCI5スタート

       R_Config_SCI5_Start(void)

       while(1)

       {

                receive();

                transmit();

        }

}

void recive(void)

{

      R_Config_SCI5_Serial_Receive(&RxBuffer ,1);

void transmit(void)

{

      R_Config_SCI5_Serial_Send(&RxBuffer, 1);

}

-----------------------------------------------------

下記自動生成されたコードの一部を編集してます。

static void r_Config_SCI5_receive_interrupt(void)
{
//if (g_sci5_rx_length > g_sci5_rx_count)
//{
//*gp_sci5_rx_address = SCI5.RDR;
//gp_sci5_rx_address++;
//g_sci5_rx_count++;
//}

  SCI5.TDR = SCI5.RDR;  //TDRにRDRを挿入し、受信データを返す。

//if (g_sci5_rx_length <= g_sci5_rx_count)
//{
/* All data received */
SCI5.SCR.BIT.RIE = 0U;
SCI5.SCR.BIT.RE = 0U;
r_Config_SCI5_callback_receiveend();
//}
}

 

static void r_Config_SCI5_transmitend_interrupt(void)
{
/* Set TXD5 pin */
PORTA.PMR.BYTE &= 0xEFU;

SCI5.SCR.BIT.TIE = 0U;
SCI5.SCR.BIT.TE = 0U;
SCI5.SCR.BIT.TEIE = 0U;

r_Config_SCI5_callback_transmitend();
}

 

Parents
  • R_Config_SCI5_Serial_Receive() に関する認識に問題があると思われます。
    この関数は、あくまで「受信設定(受信したデータ保存する場所と受信するバイト数の設定)」のみで、受信するまで待つことは有りません。

    したがって、main関数内のwhile文の中では、「受信した時の設定 → 送信開始」を常に繰り返しているので、受信したデータを延々と送信している状況です(最初のデータを受信する前は'\0"を出していたのでは?)。

    目的のプログラムにするには、while文の中を「受信設定 → 1バイト受信するまでWait → 受信した時に1度だけ送信を実施」とすれば良いと考えます。
  • 吉光屋の次男坊さん

    デバッガーで変数をウォッチ式で見ながら確認しました。

    >R_Config_SCI5_Serial_Receive() に関する認識に問題があると思われます。
    確かに、この関数は受信データのアドレスとバイト数を設定しているようです。

    >1バイト受信するまでWait → 受信した時に1度だけ送信を実施
    これはどう書けば良いのでしょうか?初心者すぎる質問ですみません。

    まず、受信割り込み処理関数を下記のように元の生成コードに戻しました。
    static void r_Config_SCI5_receive_interrupt(void)
    {
    if (g_sci5_rx_length > g_sci5_rx_count)
    {
     *gp_sci5_rx_address = SCI5.RDR;
     gp_sci5_rx_address++;
     g_sci5_rx_count++;
    }

    if (g_sci5_rx_length <= g_sci5_rx_count)
    {
     /* All data received */
     SCI5.SCR.BIT.RIE = 0U;
     SCI5.SCR.BIT.RE = 0U;
     r_Config_SCI5_callback_receiveend();
    }
    次に、メインの処理で

       unsigned int counter = 0;
    if ( MD_OK == R_Config_SCI5_Serial_Receive(&rBuff, 1) )
    {
    counter++;

    if ( counter == 1 )
    {
    R_Config_SCI5_Serial_Send(&rBuff, 1);
    counter = 0;
    }

    }
    のように設定しました。
    受信割り込みはかかり、static void r_Config_SCI5_receive_interrupt(void)の
    if (g_sci5_rx_length > g_sci5_rx_count)
    {
     *gp_sci5_rx_address = SCI5.RDR;
     gp_sci5_rx_address++;
     g_sci5_rx_count++;
    }
    の箇所にSCI5.RDRの値が入ることを確認しました。
    が、ここからが分からないところです。1バイト受信するまでWaitという書き方がこれらの関数を
    使ってどう書けばよいかわからないため、依然として送った1バイトのデータが無数に帰ってきたままです。
    送信割り込み関数の
    static void r_Config_SCI5_transmit_interrupt(void)
    {
    if (0U < g_sci5_tx_count)
    {
    SCI5.TDR = *gp_sci5_tx_address;
    gp_sci5_tx_address++;
    g_sci5_tx_count--;
    }
    else
    {
    SCI5.SCR.BIT.TIE = 0U;
    SCI5.SCR.BIT.TEIE = 1U;
    }
    }
    のelseに処理が移れば止まると思うのですが・・。
Reply
  • 吉光屋の次男坊さん

    デバッガーで変数をウォッチ式で見ながら確認しました。

    >R_Config_SCI5_Serial_Receive() に関する認識に問題があると思われます。
    確かに、この関数は受信データのアドレスとバイト数を設定しているようです。

    >1バイト受信するまでWait → 受信した時に1度だけ送信を実施
    これはどう書けば良いのでしょうか?初心者すぎる質問ですみません。

    まず、受信割り込み処理関数を下記のように元の生成コードに戻しました。
    static void r_Config_SCI5_receive_interrupt(void)
    {
    if (g_sci5_rx_length > g_sci5_rx_count)
    {
     *gp_sci5_rx_address = SCI5.RDR;
     gp_sci5_rx_address++;
     g_sci5_rx_count++;
    }

    if (g_sci5_rx_length <= g_sci5_rx_count)
    {
     /* All data received */
     SCI5.SCR.BIT.RIE = 0U;
     SCI5.SCR.BIT.RE = 0U;
     r_Config_SCI5_callback_receiveend();
    }
    次に、メインの処理で

       unsigned int counter = 0;
    if ( MD_OK == R_Config_SCI5_Serial_Receive(&rBuff, 1) )
    {
    counter++;

    if ( counter == 1 )
    {
    R_Config_SCI5_Serial_Send(&rBuff, 1);
    counter = 0;
    }

    }
    のように設定しました。
    受信割り込みはかかり、static void r_Config_SCI5_receive_interrupt(void)の
    if (g_sci5_rx_length > g_sci5_rx_count)
    {
     *gp_sci5_rx_address = SCI5.RDR;
     gp_sci5_rx_address++;
     g_sci5_rx_count++;
    }
    の箇所にSCI5.RDRの値が入ることを確認しました。
    が、ここからが分からないところです。1バイト受信するまでWaitという書き方がこれらの関数を
    使ってどう書けばよいかわからないため、依然として送った1バイトのデータが無数に帰ってきたままです。
    送信割り込み関数の
    static void r_Config_SCI5_transmit_interrupt(void)
    {
    if (0U < g_sci5_tx_count)
    {
    SCI5.TDR = *gp_sci5_tx_address;
    gp_sci5_tx_address++;
    g_sci5_tx_count--;
    }
    else
    {
    SCI5.SCR.BIT.TIE = 0U;
    SCI5.SCR.BIT.TEIE = 1U;
    }
    }
    のelseに処理が移れば止まると思うのですが・・。
Children
No Data