[H8-ML(3291)] Re: 割込みによるシリアル通信について
From: suzuki@xxxxxxxxxx (鈴木 政之)
Date: 2003年05月26日(月)20時17分16秒
鈴木です。
みなさま、大変お世話になりました。
大きく進展しましたので、
2つのプログラムをご報告申し上げます。---

天池様、hamayan様、ひやした様、を始めとして、
多くの方のご助力の結果、下記の1番目のプログラムにより
パソコンから送った、文字列(例:TEST、12345など)
が割り込みにより受信されました。・・・
が2番目のプログラムでは、うまく動作しませんでした。

-----(プログラム1)---------------------------------
#include <3064.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysio.h>

unsigned char RXBUF[50];	/* 受信バッファ */
unsigned char rx_len;		/* 受信用MSG長 */
unsigned char rx_phase;		/* 0:待機 1:受信中 2:処理中 */

/* シリアル通信初期化*******************************/
void sci0_init(void){
	SCI0.SCR.BYTE = 0x00;   /* SCI0設定 stop,内部クロック */
	SCI0.SMR.BYTE = 0x00;   /* data8.stop1,pari non Clockφ/4(1) */
	SCI0.BRR = 80;	        /* 25MHz Clockφ/4(1) 2400bps */
	#asm nop                /* Wait 1bit transfer time */
	SCI0.SCR.BYTE = 0x70;   /* Tx,Rx有効 ,受信割込み有効 */
	SCI0.SSR.BYTE &= 0x80;  /* エラーフラグのクリア */
	return;
}

/* SCI0から割込みで1文字受信する**(ベクタ番号53)****************/
interrupt void RXI0_Interrupt(void) {
	char data;			/* 受信データ変数宣言 */
	data = SCI0.RDR;		/* data 取り出し */
	if (SCI0.SSR.BYTE & 0x38) {
		SCI0.SSR.BYTE &= 0x87;	/* エラークリア */
	}
	else {
		SCI0.SSR.BYTE &= 0xbf;  /* 受信フラグクリア */
		RXBUF[rx_len++] = data;	/* バッファへの書き込み */
		rx_phase = 1;		/* 受信データあり */
	}
}

/* SCI0からの受信エラー割り込み**(ベクタ番号52)****************/
interrupt void ERI0_Interrupt(void) {
	rx_phase = 0;			/* 受信やり直し */
	rx_len = 0;			/* ポインタリセット */
	SCI0.SSR.BYTE &= ~(0x38);	/* ORER/FER/PER フラグクリア */
}

/* メイン関数***********************************************/
void main(void) {
	sci0_init();	/* シリアル通信初期化 */

	/* 受信開始 */
	rx_phase = 0;
	_ei();	
	while(1) {
		if (rx_phase == 1) {
			/* RXBUFのデータを使った処理を書く */
			printf("受信データ:%s\n",RXBUF);
			printf("\n");
			rx_phase = 0;
			rx_len = 0;	/* 受信開始 */
		}
	}
}
------------------------------------------------------


第2番目のプログラムですが、受信フルの割り込みが起こると
割り込み処理(RXI0_Interrupt関数)に飛んでいますが、
  while((SCI0.SSR.BYTE & 0x40) == 0x40){ /* RDRF(受信データフル)の確認 */
	RXBUF[rx_len++] = SCI0.RDR;	 /* バッファへの書き込み */
	rx_phase = 1;			 /* 受信データがあるよん */
  }
で、無限ループになってしまい、メインルーチンに戻らなくなってしまいます。
何か、コメントをいただけましたら幸いに存知ます。

-----(プログラム2)---------------------------------
#include <3064.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysio.h>

unsigned char RXBUF[50];	/* 受信バッファ */
unsigned char rx_len;		/* 受信用MSG長 */
unsigned char rx_phase;		/* 0:待機 1:受信中 2:処理中 */

/* シリアル通信初期化*******************************/
void sci0_init(void){
	SCI0.SCR.BYTE = 0x00;   /* SCI0設定 stop,内部クロック */
	SCI0.SMR.BYTE = 0x00;   /* data8.stop1,pari non Clockφ/4(1) */
	SCI0.BRR = 80;	        /* 25MHz Clockφ/4(1) 2400bps */
	#asm nop                /* Wait 1bit transfer time */
	SCI0.SCR.BYTE = 0x70;   /* Tx,Rx有効 ,受信割込み有効 */
	SCI0.SSR.BYTE &= 0x80;  /* エラーフラグのクリア */
	return;
}

/* SCI0から割込みで1文字受信する**(ベクタ番号53)****************/
interrupt void RXI0_Interrupt(void) {
	if (rx_phase == 2) {
		SCI0.SSR.BYTE &= ~(0x40);	/* RDRFフラグをクリア */
		return;				/* 受信データ処理中なら無視 */
	}
	while((SCI0.SSR.BYTE & 0x40) == 0x40){	/* RDRF(受信データフル)の確認 */
		RXBUF[rx_len++] = SCI0.RDR;	/* バッファへの書き込み */
		rx_phase = 1;			/* 受信データがあるよん */
      ----- ここで無限ループ  --------
	}
	SCI0.SSR.BYTE &= ~(0x40);		/* RDRFフラグをクリア */
}

/* SCI0からの受信エラー割り込み**(ベクタ番号52)****************/
interrupt void ERI0_Interrupt(void) {
	rx_phase = 0;				/* 受信やり直し */
	rx_len = 0;				/* ポインタリセット */
	SCI0.SSR.BYTE &= ~(0x38);		/* ORER/FER/PER フラグクリア */
}

/* メイン関数***********************************************/
void main(void) {
	sci0_init();	/* シリアル通信初期化 */
	
	/* 受信開始 */
	rx_phase = 0;
	_ei();
	while(1) {
		if (rx_phase == 1) {
			rx_phase = 2;	/* 処理中にする */
			/* RXBUFのデータを使った処理を書く */
			printf("受信データ:%s\n",RXBUF);
			rx_phase = 0;
			rx_len = 0;	/* 受信開始 */
		}
	}
}
------------------------------------------------------

以上です。

----
鈴木 政之  suzuki@xxxxxxxxxx

スレッド概略
[3288(R)](起点)
 └[表示中]
   ├[3292(1)]
   └[3294(2)]


投稿順に移動
[←前の記事へ(P)]
[→次の記事へ(N)]


リスト表示へ
[このスレッド(T)]
[本記事の前後(L)]