|
Top -> SH7125 -> シリアル通信を使う
シリアル通信を使うマイコン同士やマイコンとPCでシリアル通信を行う、SCIモジュールを使ってみます。初期設定
レジスタの設定void SCI1_setup(int br){ int i; STB.CR3.BIT._SCI1=0; // SCI1 動作開始 SCI1.SCSCR.BYTE = 0x00; SCI1.SCSCR.BIT.CKE = 0x00; // クロックソース SCI1.SCSMR.BYTE = 0x00; // 調歩同期式, // 8bit, // パリティ無し, // ストップビット1, // マルチプロセッサ無し SCI1.SCSMR.BIT.CKS = 0; // クロック SCI1.SCSDCR.BIT.DIR = 0x00; // LSBから送受信 SCI1.SCBRR = Pphi*2*1000000/64/br-(115200>br); // ボーレートの設定 for(i=0;i<65000;i++); // 1byte期間待つ PFC.PACRL1.BIT.PA3MD = 1; // PA3 端子機能設定 RXD1入力 PFC.PACRL2.BIT.PA4MD = 1; // PA4 端子機能設定 TXD1出力 SCI1.SCSCR.BYTE = 0x30; // 送受信許可 }Pphiは通常25[MHz]です。(Pphi=25) ボーレートの計算が怪しいかもしれません。 当方の環境では115200bpsより速くすると通信できなくなります。 teraterm等は以下のような設定にします。
送信用の関数
void SCI1_tx(char data){ while(SCI1.SCSSR.BIT.TDRE == 0); // SCTDRが空くまで待つ SCI1.SCSSR.BIT.TDRE = 0; // フラグクリア SCI1.SCTDR = data; // SCTDRに送信データを書き込む }前(正確には前の前)の送信が終わるとTDREのビットが立つのでそれを待ち、送信データを書き込みます。 マイコンの動作から見るとシリアル通信はかなり遅いので、ここで多少なりとも待たされることになります。 受信用の関数
char SCI1_rx(void){ char data; while (SCI1.SCSSR.BIT.RDRF == 0); // 受信待ち SCI1.SCSSR.BIT.RDRF = 0; // フラグクリア data = SCI1.SCRDR; return data; }1文字受信し、その値を返します。 ここで注意すべきは、何かしら受信するまでwhileで待ち続けるということ。 受信を待たずに、RDRFがゼロだったらエラーを返すような関数にした方が良いかもしれませんね。 関数を使ってみる
では、上記の関数を使ってみましょう。パソコンから受信した文字をそのまま返します。 ここでは、ボーレートを9600bpsとしているので、teratermでの設定も同様にしてください。 void main(void){ char data; SCI1_setup(9600); while(1){ data = SCI1_rx(); //パソコンから受信 SCI1_tx(data); //受信したデータをそのまま返す } } 便利な関数たちを作ってみました
lib_SCI_buff_101217.zip 準備 void intSCI1_tx_buff(void);intprg.cのINT_SCI1_TXI1内から上記関数を呼び出してください。 また、resetprg.cの#define SR_Initは0x00000000にします。 通常の送信関数では、前の1バイトの送信が終わるのを待ってから次の1バイトを送信用のレジスタに書き込むのですが、9600bpsでは1文字送るのに0.8msと、長い間待つことになります。 その待ち時間を減らすため、送信データをバッファに蓄えておき、送信が終わったことを示す割り込みによって次のデータに移ります。 バッファがいっぱいにならない限りは送信待ちがなく、プログラムがストップしないようになっています。 初期化 void SCI1_setup(int);引数はボーレートです。 送信 void SCI1_printf(char *, ...); void SCI1_tx_str(char *); char SCI1_tx_char(char); void SCI1_tx_d(long); void SCI1_tx_x(long); void SCI1_tx_X(long);基本的にはSCI1_printfを使えばokです。使い方は普通のprintfと同じで、%d,%x,%X,%c,%sに対応しています。 そのほかのSCI1_tx_str〜Xの関数は、それぞれの文字/数字だけを送りたいときに使うと、SCI1_printfよりもほんの少しだけ速いはずです。 受信 char SCI1_rx_char(void); char SCI1_rx_char_nowait(void); unsigned int SCI1_rx_d(void);SCI1_rx_charは1文字受信。受信するまで待ちます。 _nowaitは受信を待たず、もしデータが来ていないときは0x15を返します。 _dは、キーボードなどからの数字入力を受け付けます。数字入力後、エンターキーで確定し、unsigned int型の数値にして返します。 |