/***************************************************/ /* シリアル通信割込み受信テスト RIKIYA 2001.5.31 */ /* sertest2.c */ /* AKI-H8 3048/F */ /* ハイパーターミナルから投げるコマンドを、 */ /* 割込みで受信して、ハードウエア制御を行なう。 */ /* コマンド */ /* 1 : LEDを早く点滅 */ /* 2 : LEDを中くらいで点滅 */ /* 3 : LEDを遅く点滅 */ /* S : 文字入力モード エンターで終了 */ /* */ /* 通信条件は以下の通り */ /* ボーレート 9600bps */ /* データ長 8bit */ /* ストップビット 1 */ /* パリティ 無し */ /* フロー制御 無し */ /***************************************************/ #include <3048f.h> #pragma interrupt(intrxi1) /*割込み関数指定*/ extern char RXD1; /*SCI1 受信データ*/ extern char STR; /*文字列の最初の文字*/ /* メイン関数***********************************************/ void main(void){ int i,input; P3.DDR = 0xff; /*port3出力に設定 液晶表示制御用*/ P5.DDR = 0xff; /*port5出力に設定 LED表示用*/ timer_init(); /*タイマー0の初期化 */ timer1_init(); /*タイマー1の初期化 */ lcd_init(); /*液晶表示器の初期化*/ sci1_init(); /*シリアルポート1の初期化*/ RXD1 = '1'; /*受信データグローバル変数初期化*/ input = 1; /*RXD1に合わせて1にしておく*/ /*パソコン画面表示*/ sci1_strtx("[COMMAND MANUAL]"); sci1_tx('\r'); sci1_tx('\n'); sci1_strtx("INPUT 1 key : LED1/2 blink FAST"); sci1_tx('\r'); sci1_tx('\n'); sci1_strtx("INPUT 2 key : LED1/2 blink MIDDLE"); sci1_tx('\r'); sci1_tx('\n'); sci1_strtx("INPUT 3 key : LED1/2 blink SLOW"); sci1_tx('\r'); sci1_tx('\n'); sci1_strtx("INPUT s key : input strings : Enter finish"); sci1_tx('\r'); sci1_tx('\n'); sci1_tx('\n'); /*液晶表示 */ lcd_locate(0,1); /*液晶表示位置指定*/ lcd_print("READY GO!"); /*入力文字の表示*/ /* シリアルポート1割込み許可 */ SCI1.SCR.BIT.RIE = 1; /* 受信割込み許可 */ /* メイン関数での主なお仕事はLEDの点滅だけ */ while(1){ input = RXD1 & 0x0f; /*アスキーコード→数字変換 */ P5.DR.BYTE = 0x01; /*LED5 ○●表示 */ wait1(100*input); /*LED点灯周期設定*/ P5.DR.BYTE = 0x02; /*LED5 ●○表示 */ wait1(100*input); /*LED点灯周期設定*/ } } /* SCI1から割込みで1文字受信する***************************/ void intrxi1(void){ char data; /* 受信データ変数宣言 */ switch(SCI1.SSR.BIT.RDRF) /* 受信状態判定 */ { case 1: /* RDRF=1 正常受信 */ data = SCI1.RDR; /* data 取り出し */ SCI1.SSR.BIT.RDRF = 0; /* 受信フラグクリア*/ break; default: /* エラー発生時 */ SCI1.SSR.BYTE &= 0xc7; /* エラーフラグクリア */ return; } /* 入力コマンド判定処理 */ switch(data) /*入力文字判定 */ { case '1': case '2': case '3':RXD1 = data; /*グローバル変数への代入*/ sci1_tx(data); /*入力データをPCに返送 */ sci1_tx('\r'); /*リターン行頭へ移動*/ lcd_locate(0,0); /*液晶表示位置指定*/ lcd_write4(data,1); /*入力文字の表示*/ break; case 's': case 'S':str_read(); /*文字列入力処理*/ break; } } /*文字列読み込み関数***************************************/ str_read(){ char rx_data; /*受信データ*/ char *p; /*ポインタ変数*/ SCI1.SCR.BIT.RIE = 0; /* 受信割込み禁止 */ p = &STR; /*STR変数のアドレスにする*/ sci1_strtx("Strings Input Mode"); /*メッセージをPCに送信 */ sci1_tx('\r'); /*カーソル行頭*/ sci1_tx('\n'); /*改行*/ lcd_locate(0,1); /*液晶表示位置指定*/ lcd_print(" "); /*液晶2行目クリア*/ lcd_locate(0,1); /*液晶表示位置指定*/ do{ rx_data = sci1_rx(); /* 1文字受信 */ if(rx_data != '\r'){ lcd_write4(rx_data,1); /* 1文字液晶表示 */ *p = rx_data; /* 1文字を文字列に格納 */ sci1_tx(*p); /* 1文字送信 */ p++; /* 次の文字アドレスへ */ } }while(rx_data != '\r'); /* リターン入力を検出 */ *p = '\0'; /* 文字列最後はNULL */ sci1_tx('\r'); /*カーソル行頭*/ sci1_tx('\n'); /*改行*/ sci1_strtx(&STR); /*文字列をPCに送信 */ sci1_tx('\r'); /*カーソル行頭*/ sci1_tx('\n'); /*改行*/ SCI1.SCR.BIT.RIE = 1; /* 受信割込み許可 */ return; } /* シリアル通信初期化*******************************/ sci1_init(void){ SCI1.SCR.BYTE = 0x00; /* SCI1設定 stop,内部クロック */ SCI1.SMR.BYTE = 0x00; /* data8.stop1,pari non */ SCI1.BRR = 51; /* 9600bps */ wait(1); SCI1.SCR.BYTE = 0x30; /* Tx,Rx有効 ,割込み無効 */ SCI1.SSR.BYTE &= 0x80; /* エラーフラグのクリア */ return; } /* SCI1から1文字受信する****************************/ sci1_rx(void){ char data; while((SCI1.SSR.BYTE & 0x78)==0); /* 受信とエラーのフラグが立つまで待つ*/ if(SCI1.SSR.BIT.RDRF == 1){ /* データ受信が正常 */ data = SCI1.RDR; /* データを受け取りdataに保存 */ SCI1.SSR.BIT.RDRF = 0; /* 受信フラグのクリア*/ return(data); } else{ /* データ受信にエラー発生 */ SCI1.SSR.BYTE &= 0xc7; /* エラーフラグをクリア */ return(0xff); /* エラー時はFFを返す */ } } /* SCI1に1文字送信する */ sci1_tx(char data){ while(SCI1.SSR.BIT.TDRE == 0); /*未送信データが送られるまで待つ*/ SCI1.TDR = data; /*送信データのセット*/ SCI1.SSR.BIT.TDRE = 0; /*送信フラグのクリア*/ return; } /* SCI1に文字列を送信する 文字列は'\0'で締めくくっておく**************/ sci1_strtx(char *str){ while(*str != '\0'){ /* 文字が\0になるまで繰り返す */ sci1_tx(*str); /* 1文字送信*/ str++; /* 次の文字に移る*/ } return; } /********** LCD表示制御 **********/ /* lcdのリセット動作*/ lcd_init(void){ P3.DDR = 0xff; /*P3全bit出力モード*/ wait(50); P3.DR.BIT.B4 = 0; /*RS clear*/ lcd_write8(0x23); /*X,X,E,RS,7,6,5,4 = 0010 0011*/ P3.DR.BIT.B4 = 0; /*RS clear*/ lcd_write8(0x23); /*X,X,E,RS,7,6,5,4 = 0010 0011*/ P3.DR.BIT.B4 = 0; /*RS clear*/ lcd_write8(0x23); /*X,X,E,RS,7,6,5,4 = 0010 0011*/ P3.DR.BIT.B4 = 0; /*RS clear*/ lcd_write8(0x22); /*X,X,E,RS,7,6,5,4 = 0010 0010*/ lcd_write4(0x28,0); /*X,X,E,RS,7,6,5,4 = 0010 1000*/ lcd_write4(0x0e,0); /*X,X,E,RS,7,6,5,4 = 0000 1110*/ lcd_write4(0x06,0); /*X,X,E,RS,7,6,5,4 = 0000 0110*/ return; } /* lcdに8bitデータを書き込む*/ lcd_write8(char str){ P3.DR.BIT.B5 = 1; /*E-bitを1とする */ P3.DR.BYTE = str; /*strをport3に出力 */ wait(2); P3.DR.BIT.B5 = 0; /*E-bitを0とし、このタイミングで書き込む */ wait(2); return; } /* lcdに4bitデータを書き込む */ lcd_write4(char str,int rs){ char dummy = str; int status = 0; switch (rs){ case 1: /* rs = 1 データ */ P3.DR.BIT.B4 = 1; break; case 0: /* rs = 0 コマンド*/ P3.DR.BIT.B4 = 0; break; default: break; } /*上位4bitの転送*/ P3.DR.BIT.B5 = 1; /*E-bitを1とする */ dummy = dummy>>4; /*上位4bitを下位4bitにシフト*/ dummy &= 0x0f; /*上位4bitをマスクする*/ status = P3.DR.BYTE & 0xf0; /* E,RS信号以外をマスク */ P3.DR.BYTE = status | dummy; /* statusとdummyの合成を出力 */ wait(2); P3.DR.BIT.B5 = 0; /*このタイミングでlcdに書き込み*/ wait(2); /*下位4bitの転送*/ P3.DR.BIT.B5 = 1; /*E-bitを1とする */ dummy = str; dummy &= 0x0f; /*上位4bitをマスクする*/ status = P3.DR.BYTE & 0xf0; /* E,RS信号以外をマスク */ P3.DR.BYTE = status | dummy; /* statusとdummyの合成を出力 */ wait(2); P3.DR.BIT.B5 = 0; /*このタイミングでlcdに書き込み*/ wait(2); return; } /* lcdカーソル位置指定 x:0,y:0,1*/ lcd_locate(int x,int y){ lcd_write4(0x80+x+y*0x40,0); } /* lcdへの文字列書き込み */ lcd_print(char *str){ while(*str != '\0'){ /* 文字列の最後を検出 */ lcd_write4(*str,1); /* 文字の書き込み */ str++; /* 次の文字ポインタに移動 */ } return; } /********** 待ち時間発生 **********/ /* 待ち時間発生初期化 */ timer_init(void){ ITU0.TCR.BYTE = 0x23; /* GRAコンペアマッチ clock 1/8 */ ITU0.GRA = 0x07d0; /* GRAを2000に設定 */ ITU.TSTR.BIT.STR0 = 0; /* カウント停止状態 */ return; } /* 待ち時間発生 引数に必要なミリ秒を指定する */ wait(int msec){ int i; ITU.TSTR.BIT.STR0 = 1; /* ITU0 TCNTカウント開始 */ for(i=0;i