RX621マイコンでのSCI通信について

お世話になります _motoです。

以前、シリアル通信についての質問をさせて頂きました。
SCIポートの作成もして、SCI通信をしようとしているのですが、思うように動作しません。

環境
・windows7
・RX621マイコン
・開発環境 HEW
・シリアル通信 テラターム
・通信 PC⇒RS232C⇒マイコンのSCIポート

動作
PCで数値を入力する
  ↓
その数値に応じた値を8bitLEDに表示

例)数値5 ⇒ LLLL\,LHLH

以下に、作成したプログラムを添付します

#include \”iodefine.h\”
#include <machine.h>

void InitSci2();
void sendData(char key);

void main(void){
int RData\,RDatax;
clrpsw_i();
//割り込みマスク変更禁止

InitSci2();
//SCI2の初期化

PORTA.DDR.BYTE = 0xFF;
//出力ポート

while(1){
if(SCI2.SSR.BIT.RDRF){
//受信できたらフラグが立つ

SCI2.SSR.BIT.RDRF = 0;
//受信フラグを解除

RData = SCI2.RDR;
//受信データをRDataに格納

sendData(RData);
//受信データをそのまま送信

RDatax = RData & 0x0F;
//受信データのマスク

PORTA.DR.BYTE = RDatax;
//マスクをかけたデータをLEDに表示

}
}
}

void InitSci2(void){
unsigned int dmy;
//初期設定

IOPORT.PFFSCI.BIT.SCI2S = 0;
//SCI2の使用設定

SCI2.SCR.BYTE = 0;
//シリアルコントロールレジスタ(SCIの送信/受信動作設定)

SCI2.SMR.BYTE = 0;
//シリアルモードレジスタ(SCIの通信フォーマットの設定)

SCI2.BRR = 80;
//9600bps

for(dmy = 280;dmy > 0;dmy--);
//Wait 1bit transfer time 時間稼ぎ

//動作開始設定
SCI2.SCR.BYTE = 0x70;
SCI2.SSR.BYTE &= 0x80;
}

void sendData(char key){
while(!SCI2.SSR.BIT.TDRE);
//送信完了まで待機

SCI2.TDR = key;
//送信データの格納

SCI2.SSR.BIT.TDRE = 0;
//送信フラグを立てる
}

小さな間違いでも構いませんので、ぜひご指導のほどよろしくお願い致します。
  • _motoさん

    受信フラグ(RDRF)の変化待ちする代わりに、受信完了の割り込みフラグの変化を待つのはいかがでしょう?
    マイコンの種類に関わらず、単純な送受信動作をさせる時は送受信待ちに割り込みフラグを使うとタイミングを気にせず定型処理ができるかと思います。

    while(0==ICU.IR[223].BIT.IR);//受信待ち(RXI2=223)
    ICU.IR[223].BIT.IR=0;//フラグクリア


    送信も同様に、送信エンプティフラグ(TDRE)の代わりに割り込みフラグで。
    while(0==ICU.IR[224].BIT.IR);//送信待ち(TXI2=224)
    ICU.IR[224].BIT.IR=0;//フラグクリア

  • Kirinさん ご返事ありがとうございます。

    >if(SCI2.SSR.BIT.RDRF == 1){
    の所を
    >while(0==ICU.IR[223].BIT.IR);
    に変えてもLEDに全く変化がありませんでした。
    (送信側も同様に変えました)
    テラタームにも返信が無いので、マイコンの送信プログラムも動作していない様子です。

    ハードウェアには問題ありません。

    よろしくお願い致します。
  • こんにちは、

    while(!SCI2.SSR.BIT.TDRE == 1);

    たぶん

    while(!SCI2.SSR.BIT.TDRE);

     初期設定中は割り込み禁止にしないと、割り込み関係のフラグを操作したときに不意な割り込みが入るおそれが有ります。
     これだけであなたのプログラムが直る訳じゃないけど。

     開発の順序が悪い。まず送信で同じ文字を連続でパソコンに送ります。
     これで送信プログラムを確実にします。
     次にパソコンから送った文字を送り返すプログラムを作ります。
     これで受信プログラムを確実にします。
     LEDを光らせるのは、それからです。


     I/Oの設定はマニュアルを見なくても分かるようにビットの意味をコメントで書いておくと良い。
     私のプログラムの例を示します。本当は綺麗に並んでいるのですが、此処にアップすると左詰めになったり改行が多くなったりして汚くなってしまう。

     テキストにコピーして並べ直して読んで下さい。

     このコメントを読むと、「読み出してからでないと0に出来ないフラグが有るので、ダミーリード」と有りますよ。

     ソフトは動く以外に、見てくれやコメントが重要です。料理と同じ。栄養が摂れる以外に味が良く、見た目も良い事が大切。


    /*==============================
    = 
    SCIチャネル0の設定 (マニュアル13章)


    ==============================*/

    SCI0.SCR.BYTE = 0x70
    ;
    /*







    マニュアル「13.2.6 シリアルコントロールレジスタ」







    7:TIE
    0:送信データエンプティ割り込み(TXI)要求の禁止










    DMAC-0Aの割り込み処理内で、TIE=1 にする。










    SCI-0の送信割り込み処理内で、TIE=0 にする。







    6:RIE
    1:受信データフル割り込み(RXI)要求、および受信エラー割り込み(ERI)要求を許可










    受信割り込みを許可しないとDMAは動作しなかった。










    しかし受信割り込み処理には飛ばないようです。







    5:TE
    1:送信動作を許可







    4:RE
    1:受信動作を許可







    3:MPIE
    0:マルチプロセッサ割り込み禁止状態(通常の受信動作をします)(初期値)







    2:TEIE
    0:送信終了割り込み(TEI)要求を禁止 (初期値)







    1-0:CKE
    00:調歩同期式モード 内部クロック/SCK端子は入出力ポート










    CKE1\,0 は SMR より以前に設定とマニュアルに書いてある







    */




    /* === SMR と BRR は、チャネル1の設定をチャネル0にコピー ===
    */

    SCI0.SMR = SCI1.SMR

    ;
    /*
    調歩/同期、8/7ビット、パリティ有無、偶/奇、
    */







    /* ストップビット長1/2、マルチプロセッサ、分周比選択*/
    SCI0.BRR = SCI1.BRR

    ;
    /*
    ビットレイト設定








    */

    dummy = SCI0.SSR.BYTE
    ;
    /* 読み出してからでないと0に出来ないフラグが有るので、ダミーリード
    */
    SCI0.SSR.BYTE = 0x84
    ;
    /*







    ステータス・レジスタのエラーフラグをリセット







    7:TDRE
    1: 1のとき送信データを書き込める。書き込み後、0にすると送信する。







    6:RDRF
    0: 1のとき受信データ有り







    5:ORER
    0: 1のとき受信オーバーラン・エラー







    4:FER
    0: 1のとき受信フレーミング・エラー







    3:PER
    0: 1のとき受信パリティ・エラー







    2:TEND
    1: 1のとき送信終了を示す







    1:MPB
    0: 受信したマルチ・プロセッサ・ビットを示す







    0:MPBT
    0: 送信するマルチ・プロセッサ・ビットを示す







    */
  • _motoさん

    そういえば、RXDで使用するポートの入力バッファコントロールレジスタ(ICR)は1に設定されてます?

    >周辺モジュールの入力端子として使用する場合は、
    >あらかじめ、対応する端子の入力バッファを有効にするために
    >PORTn.ICR を“1” にする必要があります。PORTn.ICR を
    >“0” にした状態のまま周辺モジュールの入力端子として使用
    >した場合は、周辺モジュールへの入力信号はHigh に固定されます。
    と書いてありますので。


    それと、MSTP(SCI2)=0;でモジュール動作を許可するのと、システムクロックの設定はHardwareSetup()等でおこなっていますでしょうか。

    それとそれとIOPORT.PFFSCI.BIT.SCI2Sレジスタで使用したいポートを選択されてます?
  • リカルドさん ご指摘ありがとうございます。
    確かに、順序が悪いですね。ですが、H8/3052では出来たプログラムをRX621でも使えるように変更するだけなのですが、それができずに悩んでいるところなのです。

    Kirinさん いつもご指導ありがとうございます。
    ・入力バッファコントロールレジスタ(ICR)
    >PORT1.ICR.BIT.B2 = 1;
    //SCI2のRxD2はPORT1の2bit
    としました

    >MSTP(SCI2)=0;
    も追加しました。

    IOポートのレジスタ設定
    >IOPORT.PFFSCI.BIT.SCI2S = 0;
    //PORT1のRxD2\,TxD2を使用
    も書かれています。

    確認のために、\”受信データの格納\”の前に
    >PORTB.DR.BYTE=0x01;
    を追加してプログラムが動作しているか見てみたのですが、PORTBには0x01が入っていなく
    受信フラグの
    >if(SCI2.SSR.BIT.RDRF == 1){
    受信完了割り込みフラグの
    >while(0==ICU.IR[223].BIT.IR);
    でもフラグが立たず、中の処理ができていなく、結果、受信できていないことになっています。

    何か、根本的に違うところがあるのでしょうか?
    よろしくお願い致します。
  • _motoさん

    レジスタ設定が正しいとすると、
    もしかしてボーレートがズレているかもしれません。

    受信処理の前に、先に送信してみるのはいかがでしょう?
    送信ならボーレートがズレていようとパリティなどの設定が間違っていようと、とにかく何か出力されるはずなので、オシロで波形確認できますから。

    あと、デバッガで、SCRなどCSI系のレジスタに書き込んだ値が正しく書き込めているかどうかなんかも確認してみてください。
  • Kirinさん ご返事ありがとうございます。

    文字化けして読み取ることはできませんでしたが、RX621とテラターム間での送信処理は一応できました。

    この、文字化けの原因はやはりボーレートのズレによるものなのでしょうか?

    \”a\”を送信すると、\”・・\”と連続して出てきます。

    ちなみに通信設定は、
    9600bps
    データビット長8ビット
    ストップビット1ビット
    パリティビットnone
    と設定しました。
    (マイコン側の速度があっているか不安ですが・・・)

    追記
    受信処理で注意しなければならないことも教えていただきたいです。

    よろしくお願い致します。
  • _motoさん

    連続して文字化けしているとすると
    RX621のクロックが遅いのかもしれませんね。
    オシロがあればいいんですけども。

    受信の注意は、相手とボーレートなどの設定が合っているのと、受信したらすぐに読み出して受信バッファがオーバーランしないようにすることでしょうね。
  • _moto さん。
    ramoth といいます。

    提示されている初期設定では、ボーレート
    に関係するパラメータで不明のものが2点あります。
    1つは PCLK の周波数、もう1つは
    SEMRレジスタのABCSビットの値です。

    9600bpsと、提示されている設定値(BRR\,SCR)から逆算すると
    SEMR.ABCS=0 の場合 PCLK=25MHz
    SEMR.ABCS=1 の場合 PCLK=12.5MHz
    となります。
    これが正しければ、ボーレート関係の設定は
    間違っていません。
    また、通信データのビット数/パリティビット等の設定
    も間違っていません。

    ボーレートの設定についての詳細は
    ユーザーズマニュアルの P. 1390-1392
    「29.2.1.9 ビットレートレジスタ (BRR)」
    を参照してください。
    こちらにはボーレートから設定値を求める方法と
    具体的な設定例が記載されているので、
    設定値の計算が正しいか検算することもできます。

    ボーレートの設定が正しい場合は、ソフトの設定では
    なくて、信号のレベルなどハードウェアの問題の
    可能性が出てきます。
    この場合は、Kirin さんからの提示のように
    オシロによる信号確認が必要になってきます。

  • Kirinさん ramothさん ご返事ありがとうございます

    本当に初歩的なことなのですが、PCLKがいくらかわからずにいます。PCLKにつながる、メインクロックもいくつかわかりません・・・
    クロック設定についてお教えください。
    >SEMRレジスタのABCSビットの値
    は、SEMR.ABCS=0です。

    ちなみに、送信関数に値を渡すとき
    >sendData(\”a\”);
    と渡しているのですが、渡し方はこれであっていますか?

    また、受信についてなのですが、受信完了フラグが立ちません。所々でLEDを用いてプログラムを追っているのですが、受信完了フラグの
    >if(SCI2.SSR.BIT.RDRF);
    が変化しないので受信データが取得できません。

    こちらについてもお教えください。

    初歩的なことを色々と質問してすいません。
    よろしくお願いいたします。

    追記
    >オシロによる信号確認
    はどこで確認すればよろしいのでしょうか?