いつもお世話になっております。パセリを食べようです。
今、私はシリアル通信で文字列受信コーディングをしております。
4バイト受信し、STX~ETXに囲まれたデータ本文が"A1"ならLED2点灯
データ本文が"A0"ならLED2消灯、
それ以外ならLED0点灯でエラーというコーディングにしたいと考えてます。
現在、A1,A0の受信コーディングは完了し、正常動作確認済みです。
※文字列送信後も、再度受付可能状態にしたい。
下記のコーデイング内容は、
①R_UART0_Receive関数で格納先指定し、
②アプリケーションソフトより文字列を送信(必ず4バイト)
③電文を受信
④割り込みで文字カウントで4文字取得したらフラグをオンにする
⑤フラグオンで文字比較
⑥比較し終わったら文字カウント0にリセット、再度受付
という仕様にしたいと考えておりまして、
エラー文字送信後には、文字の再度受付ができなくなっています。
お聞きしたいことは3つあります。特に③を知りたいと思っています。①R_UART0_Receive関数は、whileに入れる場合と入れない場合の動作の違いは、 カウントを0にリセットしているという一点のみの違いでしょうか。 (whileに入れてしまうと、呼び出される度にバッファの場所の指定と サイズの指定がされている)
②R_UART0_Receive関数のバッファの指定をしたい場合はwhile外に記述し、 rx_countを別の部分でリセットを書けるようにしたいのですが、 このやり方ですと何か問題はありますでしょうか。 (私のコーディング内容の場合、rx_countをexternし、4文字受け取ったら 0にリセットするという風にコーディングしております。
②R_UART0_Receive関数は戻り値を仕様している方を見たことが無いのですが、 使用する場合、私のコードのような仕様にすると何か問題は ありますでしょうか。 バッファ設定・正常完了ならば、後続処理へという風にしたいと考えて コーディングしました。
③"A1","A0"の打ち込み→受信で『LED点灯/消灯』 それ以外の場合はNGWORDをフラグに代入し、エラー という風にコーディングしました。 文字は再度受付可能の状態にしたいのですが、 一度エラーの文字を入力してしまうと、そのあとに"A1","A0"を 入力しても、LEDが点灯せず、という状況に悩まされています。 ※A0とA1の二つの文字を受信した場合は、 何度でも文字受信~LED点灯/消灯ができています。
【main関数内】*****************************************************************************************↓
void main(void) { uint8_t rxBuff[BUFFMAX]; //バッファ。BUFFMAXは10 uint8_t result_flag ; st_flag = NO_ERROR; //最初は正常状態 R_MAIN_UserInit(); // 割り込み許可 R_IT_Start(); // インターバルタイマスタート R_UART0_Start(); // UART開始 result_flag = R_UART0_Receive(rxBuff, 4); //4バイト分を『rxBuff[BUFFMAX]』に格納 while (1) { if(MD_OK != result_flag){ //returnを比較。エラーでLED0点灯 st_flag = NGWORD; } else{ if (rxBuff[0] == STX) { // STXを受信したらタイマーを起動 timelimit_counter(50); // 500msのタイマーを起動→時間超過でエラー } else{ st_flag = NGWORD; } if(FLAG_ON == string_flag){ //4バイト分割り込み受信したらフラグオン if(rxBuff[0] != STX){ //先頭にSTXがない場合 st_flag = NGWORD; }else if(rxBuff[3] != ETX){ //末尾にETXが無い場合 st_flag = NGWORD; }else if(rxBuff[1] != 'A'){ //2番目の要素がAじゃない場合 st_flag = NGWORD; }else { //2番目の要素がAの場合 switch(rxBuff[2]){ case '0' : //1の場合(A1)→LED2消灯 LED2 = LED_OFF; break; case '1' : //0の場合(A0)→LED2点灯 LED2 = LED_ON; break; default: //エラー時。1でも0でも無い場合 st_flag = NGWORD; //LED0 点灯 break; } timer_flag = 1; //タイマーフラグをオンに } string_flag = FLAG_OFF; //処理の終了でフラグ&受信文字カウントリセット rx_count = 0; } } if(NGWORD == st_flag){ //エラー時処理 LED0 = LED_ON; //LED0点灯 string_flag = FLAG_OFF; //処理の終了でフラグ&受信文字カウントリセット rx_count = 0; } }}
【main関数終了】***************************************************************************************↑
【割り込み受信関数(ウィザード生成したものに加筆、調整)】*************************************↓
static void __near r_uart0_interrupt_receive(void){ volatile uint8_t rx_data; rx_data = RXD0;
if (g_uart0_rx_length > g_uart0_rx_count && 4 > rx_count) //4文字受信(カウント4)していない場合に動作 { gp_uart0_rx_address[rx_count] = rx_data; rxBuff[rx_count] = gp_uart0_rx_address[rx_count]; rx_count++; if (4 == rx_count){ string_flag = 1; } if (g_uart0_rx_length == g_uart0_rx_count) { r_uart0_callback_receiveend(); } } else { }}
【割り込み受信関数終了】******************************************************************************↑
長文なってしまい大変恐縮ですが、お力添え頂ければ幸いです。
チョコです。
>①R_UART0_Receive関数は、whileに入れる場合と入れない場合の動作の違いは、> カウントを0にリセットしているという一点のみの違いでしょうか。
それは答えられません。
どうも、R_UART0_Receive関数も変更されてしまっているのではないかと思います。
r_uart0_interrupt_receive関数で使用しているカウンタが、R_UART0_Receive関数で使っているカウンタと異なっており、
何を期待して異なる変数を使っているかが理解できません。ここらを、明確にしてください。
>②R_UART0_Receive関数のバッファの指定をしたい場合はwhile外に記述し、> rx_countを別の部分でリセットを書けるようにしたいのですが、
カウンタの使い分けをよく見直してください。提示されていない情報がないと判断できません。
割り込み処理に「if (g_uart0_rx_length == g_uart0_rx_count)」の判断がありますが、「g_uart0_rx_count」はどこでもカウント処理されていないので、この条件式が成立することはありません。
>②R_UART0_Receive関数は戻り値を仕様している方を見たことが無いのですが、> 使用する場合、私のコードのような仕様にすると何か問題は> ありますでしょうか。
問題はないと思いますが、この戻り値がエラーになるのは引数のデータ数が0の場合だけなので、このようにデータ数が4に固定の場合には、無意味だと思います。
>一度エラーの文字を入力してしまうと、そのあとに"A1","A0"を> 入力しても、LEDが点灯せず、という状況に悩まされています。
問題は、提示された部分以外にあるのではないですか。
例えば、timer_flagは正常な場合だけにセットしているようですが、これが影響していることはないでしょうか。
とにかく、「きちんとした情報がないので、答えられない。」です。
以上
チョコ様
いつもお世話になっております。
今回の情報提供に関して、かなりおおざっぱなものになってしまい申し訳ありませんでした。
おっしゃっていることはごもっともです。そんな中でご回答いただきましてありがとうございました。
いささかこのサイトに頼りきりになってしまった部分が多かったように感じます。
お忙しい中、どうもありがとうございました。ここから自力で考え、これから先質問することがある場合、より具体的な情報提供を心がけます。