現在、RXマイコンを使用してSCI通信を行っているのですが、
データの受け取りをバッファ配列のアドレス移動を行い、そこにデータを格納しています。
受信文字列の終端文字を確認するために、コールバック関数内で判定を行っているのですが、受信データの格納位置と条件式で参照しているメモリアドレスが異なり、
条件式が正となりません。
SCI通信時の受信データの格納方法が通常と異なるように思えるのですが、どのようにすればよいでしょうか。
以下に受信データのメモリ参照の画像と、コールバック関数のコードについて添付します。
よろしくお願いします。
これはスマートコンフィギュレータのSCIでコールバック機能設定の受信完了を有効化したときの状態ですよね?最初の条件判定が一度も真にならないということでしょうか?PC_Receive_Dataにvolatile宣言があるとうまくいくとかあるかもしれません。それより気になるのことですが、R_SCI_XXX_ReceiveのAPIを実行して1文字ごとユーザーコールバックr_XXX_callback_receiveendを呼び出してもらって終端判定をするという作りと思いますが、送信データが既知ならPC_Receive_Data配列(大域変数?)が同じ値を受け取っているかが気になります。というのもUART通信データは送り出す側はバッファを使うのでデータとデータの送信間隔は長くてスタートビット長くらいしか間がありませんが、このプログラムの作りですと1バイト受信して完了したら次の1バイト受信の要求をR_SCI_XXX_Receiveを使って要求しています。受信でデータが抜けているのではないかと思いました。というのも生成コードの実際のSCIの受信割込みハンドラはR_SCI_XXX_Receiveで要求されたバッファサイズの受信が完了すると一度REビットをクリアしてからr_XXX_callback_receiveendを呼び出す作りになっているためです。受けったと思われるデータ列
4E 49 49 00 => 'N' 'I' 'I' null
30 30 31 54 => '0' '0' '1' '6'
49 0A 0D 30 => 'I' LF CR '0'
30 31 54 4E => '0' '1' '6' 'N'
0A 0D 30 30 => LF CR '0' '0'
この部分が受信データなら0016NIIというような文字列が来ているように思えますし、二回目と思われる位置のIIが抜けている。データの仕様などを推測で書いているので本当かはわかりませんが。
あと質問からそれますがmemsetでバッファクリアをしていますね、はっきり申し上げて要らないです。割込み空間で余分な処理は極力避けるべきです。
もし、送っているデータが既知で抜けが起こっていると思われる状況なら生成コードのr_XXX_receive_interruptでREビットを0にしている部分を一時的にコメントアウトして受信状況がどう変わるか見るのも私なら試します。あとスマートコンフィギュレータの生成コードは多重割込みが許されていない状態のものですのでSCIの他に割込み駆動で高優先度なものがあるとデータ抜けの原因になったりします。私ならDTCなどで別途、塊のデータをハード的に退避する作りにします。
Yamamotoさん、NoMaYさん
回答ありがとうございます。
レシーブ関数を使用する時にレシーブポジションをインクリメントしてしまっているので、もう一度その部分については確認したいと思います。
受け取りの文字列はINT10、INT100、INT1000、EXT、STOPの5種類の文字列で各文字列の終端にCRLFが付与されて送信されます。
メモリブラウザを見る限り、データの受け取りは問題なく出来ているように思います。(始めの部分はコールバック関数内でブレークポイントを入れてしまったので、文字列の読み取りが変になってしまいました。)
文字列の長さがそれぞれ異なるため、文字数での判定が出来ず、1文字ずつ読取る方法で終端文字の判別を行おうと考えていたのですが、RXマイコンではどのようにデータの読み取りを行うのが最適なのでしょうか。
RXマイコンに限った話の正攻法ってのは特にありません。SCIの仕様は他社のUARTとさほど変わりません。受信完了時の割り込みハンドラでUARTの受信バッファを内部変数に退避する仕組みを導入するだけです。
が!ことスマートコンフィギュレータは・・・私のような低レベルな者では到底理解の及ばない崇高な設計思想のためか?UARTのハンドリングは一筋縄ではいきません。一番やらかすのは多重割り込みが許可されていない点です。特にSCIの生成コードは酷いですね。私の最近の経験で言えばRS485でトランシーバICのDE端子操作をやるのに苦労しました。スマートコンフィギュレータのコードを使うと決めたら腹を据えて取り組むしかないです。
なお、他の方がどうやってるかわかりませんが、私は多重割り込みを生成コードに直接変更を加えることで解決しています(生成のたびにその変更を適用するわけです)。RS485のDE端子とかの制御についてはDTCでPORT制御のレジスタをプロセッサを通さずに書き換えることで解決したりしました。もし、受信抜けが起きている場合は受信ハンドラを直接編集するなどで簡単にやりたいことが解決したりするかもしれません。
FPGAと何かやってる関数がありますが、もし、これの処理時間が結構かかるものなら呼び出し順序の工夫も忘れずにしましょう。まずは受信データの仕様をよく確認ですね。・データの最大サイズ・データ終端後、最大送信停止時間と最小送信停止時間の確認(要するに通信サイクル)通信サイクルが明確に規定されているなら最大サイズで受信させて、タイマを別に用意して通信タイムアウトを監視させてそこで受信データの確認をさせれば良いように思います。