シリアル通信パソコン等と通信を行うためには、マイコンとは別にRS-232ドライバ/レシーバと呼ばれるICが必要です。これは、マイコン内部の電圧(3V~5V)と、RS-232通信規格で決まっている電圧(±9V)が異なるので、 電圧変換(レベル変換と言う)を行うためです。 ここで記述するシリアル通信プログラムは、UART割り込みを使用します。 SH2マイコン等では、SCI(シリアルコミュニケーションインタフェース)と呼んでいましたが、 R8C/15では、UARTと呼んでいます。 HEWの場合、ベクタアドレス関係は、「sect30.inc」ファイルに記述します。 (割り込み番号は、ハードウェアマニュアルp73参照) 「sect30.inc」ファイルの「variable vector section」の記述を下記の通り変更します。 .lword dummy_int ; vector 16 .glb _uart0_t .lword _uart0_t ; vector 17 UART0 transmit .glb _uart0_r .lword _uart0_r ; vector 18 UART0 receive .lword dummy_int ; vector 19 では、実際のプログラムを記述します。 通信速度は、マイコンのクロックに影響されますが、ここでは先に示した内臓高速オンチップオシレータにより 8MHzで駆動していることを前提とします。 ポイントは、連続的にバッファ空割り込みを使ってデータを転送するときの2個目のデータをセットするタイミングです。 バッファ空割り込みは、バッファに書き込んだデータが、実際に転送するレジスタに読み込まれたときに発生するもので、 転送中のデータを送り終わる前にバッファにデータをセットすることで次々に絶えずデータを送ることができる便利な機能です。 しかし、まず最初のデータをバッファに書き込まないと、割り込み自体が発生しないなんて不便な部分もあります。 連続転送の手順は以下の通りです。 1つ目のデータを直接バッファに書き込む。 と、ここで、1つ目のデータがバッファから転送用レジスタに送られるのを待つ。 2つ目のデータも直接バッファに書き込む。 3つ目のデータからは、FIFO配列に保存する。 1つ目のデータが転送終了、バッファにある2つ目のデータが転送用レジスタに格納、割り込み発生。 割り込み処理で、3つ目以降のデータを順次バッファに書き込めはOK。 /* UART0初期化 */ uart_init(38400, 8, 0, 1); // bps,bit,parity,stopBit asm("FSET I"); // 全体の割り込み許可 /* キャラクタコードでのエコーバック */ while(1){ data = uart_getc(); /* 1文字受信 */ if ( 0 <= data ) { uart_put_char_hex((unsigned char)data); /* 数値送信 */ uart_putc((unsigned char)0x0d); /* CR */ uart_putc((unsigned char)0x0a); /* LF */ } } /************************************************************************/ /* */ /* 通信処理プログラム */ /* */ /* CPU TYPE :R8C/Tiny 15Group (8MHz) */ /* Copyright :西 憲一郎 */ /* */ /************************************************************************/ // 注)9ビット転送には対応していません #define BUFF_SIZE 256 typedef struct { unsigned short len; unsigned short read; unsigned short write; unsigned char *buff; } FIFO; static unsigned char rxbuff[BUFF_SIZE]; static unsigned char txbuff[BUFF_SIZE]; static FIFO rxfifo; static FIFO txfifo; /****************************************/ /* UART0 初期化 */ /****************************************/ #define PCLOCK (8000000) uart_init( unsigned short bps, /* 1200~51200 */ unsigned char bit, /* 7 or 8 */ unsigned char parity, /* 0:なし 1:奇数 2:偶数 */ unsigned char stopBit ) /* 1 or 2 */ { /* RX FIFO */ rxfifo.len = 0; rxfifo.read = 0; rxfifo.write = 0; rxfifo.buff = rxbuff; /* TX FIFO */ txfifo.len = 0; txfifo.read = 0; txfifo.write = 0; txfifo.buff = txbuff; if(bit == 7) { smd2_u0mr = 1; // 調歩7bit(p140) smd1_u0mr = 0; smd0_u0mr = 0; } else { smd2_u0mr = 1; // 調歩8bit smd1_u0mr = 0; smd0_u0mr = 1; } if(stopBit == 2) { stps_u0mr = 1; // 2ストップビット } else { stps_u0mr = 0; // 1ストップビット } if(parity == 0) { prye_u0mr = 0; // パリティ禁止 } else { prye_u0mr = 1; // パリティ許可 if(parity == 1) { pry_u0mr = 0; // 奇数パリティ } else { pry_u0mr = 1; // 偶数パリティ } } ckdir_u0mr = 0; // 内部クロック u0c0 = 0x00; // f1で8MHz、CMOS出力、LSBファースト u0c1 = 0x07; // 受信許可、送信許可 ucon = 0x00; // 送信バッファ空で割り込み、連続受信禁止 u0brg = ((PCLOCK / 16) / bps) - 1; // bps設定 /* 割り込み開始 */ s0ric = 0x04; // 受信割り込み(レベル4)(p74) s0tic = 0x04; // 送信割り込み(レベル4) } /****************************************/ /* 数値出力 */ /****************************************/ short uart_put_char_hex( unsigned char data ) { char hex; hex = data>>4; hex &= 0x0F; if ( hex<10 ) { hex += 0x30; } else { hex += 55; } uart_putc(hex); hex = data; hex &= 0x0F; if ( hex<10 ) { hex += 0x30; } else { hex += 55; } uart_putc(hex); } short uart_put_short_dec( unsigned short data ) { char dec; dec = data/10000; data = data%10000; dec += 0x30; uart_putc(dec); dec = data/1000; data = data%1000; dec += 0x30; uart_putc(dec); dec = data/100; data = data%100; dec += 0x30; uart_putc(dec); dec = data/10; data = data%10; dec += 0x30; uart_putc(dec); dec = data; dec += 0x30; uart_putc(dec); } /****************************************/ /* 1文字格納 */ /****************************************/ short uart_putc( unsigned char data ) { short ret; short i; ret = -1; s0tic = 0x00; // 送信割り込み禁止 if(ti_u0c1 == 1) { // 送信バッファレジスタが空なら直接書き込む ret = data; u0tb = ret; // データ送信 for( i=0; i<10; i++){} // タイミング調整 } else { if ( BUFF_SIZE > txfifo.len ) { txfifo.buff[txfifo.write] = data; // バッファへ書き込み txfifo.len++; txfifo.write++; if ( BUFF_SIZE <= txfifo.write ) { txfifo.write = 0; } ret = data; } else { } } s0tic = 0x04; // 送信割り込み許可 return (ret); } /****************************************/ /* 1文字取得 */ /****************************************/ short uart_getc() { short data; data = -1; s0ric = 0x00; // 受信割り込み禁止 if ( 0 != rxfifo.len ) { data = rxfifo.buff[rxfifo.read]; // バッファから読み出し rxfifo.len--; rxfifo.read++; if ( BUFF_SIZE <= rxfifo.read ) { rxfifo.read = 0; } } s0ric = 0x04; // 受信割り込み許可 return (data); } /****************************************/ /* 受信割り込み */ /****************************************/ #pragma interrupt uart0_r // 受信割り込み処理関数指定 void uart0_r(void) { unsigned short data; // u0rbレジスタは必ず16ビット単位で読み出す data = u0rb; // データ取得 data &= 0x00ff; if ( BUFF_SIZE > rxfifo.len ) { rxfifo.buff[rxfifo.write] = data; // バッファへ書き込み rxfifo.len++; rxfifo.write++; if ( BUFF_SIZE <= rxfifo.write ) { rxfifo.write = 0; } } } /****************************************/ /* 送信割り込み */ /****************************************/ #pragma interrupt uart0_t // 割り込み処理関数指定 void uart0_t(void) { unsigned short data; if ( 0 < txfifo.len ) { data = txfifo.buff[txfifo.read]; // バッファから読み出し txfifo.len--; txfifo.read++; if ( BUFF_SIZE <= txfifo.read ) { txfifo.read = 0; } u0tb = data; // データ送信 } else { } } (○ルファプ○ジェクト社の7046用サンプルプログラムを参考にさせて頂きました) ジャンル別一覧
人気のクチコミテーマ
|