- ベストアンサー
H8マイコンでの割り込み(シリアルポート入力で)
マイコン:AKI H8/3048F 開発環境:GCC Developer Lite マイコンとパソコンをRS-232Cケーブルでつないでいます。 ハイパーターミナルを使用して、マイコンを制御したいと考えております。 それで、パソコンのキーボードから入力があった時だけ、割り込みを実行したいです。 割り込みが無い場合は、パソコンでマイコンを制御することができたのですが、割り込みを追加したら、うまくいかなくなりました。 アセンブラを使用せずに、C言語だけでプログラムを完成させたいと思っています。 SCI1からの割り込み処理をするには、どの様にしたらよいのでしょうか? どうか、お願いいたします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>void int_rxi1(void) >{ > DI; /*ここで他のプログラムの割り込みを禁止*/ > /*割り込みで実行させたいプログラム*/ > EI; /*割り込み許可にしてプログラムを終了*/ >} I.割込み処理ルーチンではDI,EIを行ってはいけません。 以下に示すように割込みの禁止はハードウェアがやってくれます。 割込み禁止解除は割込み処理が終了したとき実行されるRTE命令で 行われます。 ------------ H8/3048ハードウェアマニュアル -------------------- 4.1.2 例外処理の動作 例外処理は、各例外処理要因により起動されます。 トラップ命令および割り込み例外処理は、次のように動作します。 (1) プログラムカウンタ(PC)とコンディションコードレジスタ(CCR)をスタックに退避しま す。 (2) CCRの割り込みマスクビットを1にセットします。 (3) 起動要因に対応するベクタアドレスを生成し、そのベクタアドレスの内容が示す番地からプ ログラムの実行が開始されます。 【注】リセット例外処理の場合は上記(2)、(3)の動作を行います。 ------------------------------------------------------------------- II.割込み処理関数には#pragma interrupt を付けます。 #pragma interrupt void int_rxi1(void) { } なお、#pragma と関数宣言の間にコメントを入れてはいけません。 一種のおまじないです。 III. 割込み処理関数では少なくとも以下の2つを実行する。 (1)SCI1.RDRを適切な場所に保存 (2)SCI1.SCR.BIT.RDFをクリア デバッガを使えるなら、割込み処理の入り口で止めて動作を 確認して下さい。
その他の回答 (3)
- ricardo_
- ベストアンサー率19% (14/72)
割り込みフラグの処理の問題だと思います。 過去に作ったプログラムを載せますので、参考にして下さい。 今動かして見たのですが、3048と3052とで仮想割り込みベクタのアドレスを変えているためか、直ぐには動かなかった。 でも過去に動いた筈だから、参考になると思います。 プログラムの内容は忘れましたが、割り込み処理で受信データをそのまま送信する、エコーバック処理だったと思います。 揃っていなくて見苦しいけれど、コピーしてタブを4にすれば綺麗に揃うかも知れません。 元は綺麗に揃っています。 /********************************* * インクルード・ファイル * *********************************/ #include <3048F.H> /* */ /********************************* * グローバル(共通)変数 * *********************************/ volatile char SCI_BUFF[40] ; /* SCIの送受信バッファ */ /********************************* * main プログラム * *********************************/ void main(void) {EI() ; /* 割り込み許可 */ SCI1.SCR.BIT.RIE = 1 ; /* 受信割り込み許可 */ while(1){} ; /* 永久ループ */ } /********************************* * 割り込み処理 * *********************************/ #pragma interrupt(INT_ERI_1) /* 56 SCI-1 受信エラー */ #pragma interrupt(INT_RXI_1) /* 57 SCI-1 受信 */ #pragma interrupt(INT_TXI_1) /* 58 SCI-1 送信 */ /*--------------------------------------------------------------*/ void INT_ERI_1(void) /* 56 SCI-1 受信エラー */ {SCI1.SSR.BYTE &= 0xC7 ;} /* エラーフラグをリセット */ /*--------------------------------------------------------------*/ void INT_RXI_1(void) /* 57 SCI-1 受信 */ {SCI1.SSR.BIT.RDRF = 0 ; /* 受信フラグリセット */ SCI_BUFF[0] = SCI1.RDR ; /* 受信データをバッファに転送 */ SCI1.SCR.BIT.TIE = 1 ; /* 送信割り込み許可 */ } /*--------------------------------------------------------------*/ void INT_TXI_1(void) /* 58 SCI-1 送信 */ {SCI1.TDR = SCI_BUFF[0] ; /* バッファから送信データに転送 */ SCI1.SSR.BIT.TDRE = 0 ; /* 送信開始 */ SCI1.SCR.BIT.TIE = 0 ; /* 送信割り込み禁止 */ } /*------------- interrupt.C ------------------------------------*/
補足
ソースまで載せていただき、ありがとうございます。 さっそくプログラムを作り始めます。
- f-tomohiko
- ベストアンサー率50% (11/22)
No.1 です。 割込みがどんなものであるか分かっているようですから以下のページの 割込の項を読んで下さい。 http://wave.iobb.net/doc/h8/index.html#_Toc99442949 分からない事があったら、再度質問して下さい。
補足
#include<3048.h> #define EI asm("andc.b #0x3f,ccr")/*割り込み許可*/ #define DI asm("orc.b #0xc0,ccr")/*割り込み禁止*/ void int_rxi1(void)__attribute__((interrupt_handler)); main(){ /*何かしらのプログラム*/ SCI1.SCR.BIT.RIE = 1; EI; while(1){ /*基本は無限ループで割り込みがあった場合に抜けるループ*/ } void int_rxi1(void) { DI; /*ここで他のプログラムの割り込みを禁止*/ /*割り込みで実行させたいプログラム*/ EI; /*割り込み許可にしてプログラムを終了*/ } ここまでは分かったのですが、SCI1のパソコンからの入力信号で割り込みをするには、ここからどうすればよいでしょうか??
- f-tomohiko
- ベストアンサー率50% (11/22)
割込みを使用しないとOKなら割込みの使い方が分かれば簡単に済む 事のようです。 まずはSCI1の割込みベクター番号は分かりますか。?
補足
遅くなり、申し訳ありません…。 SCI1の割り込みベクタ番号は56~59まであります。 56…ERI1(受信エラー) 57…RXI1(受信完了) 58…TXI1(送信完了) 59…TEI1(送信終了) となっています。
補足
細かく解説を交えながらご回答していただき、ありがとうございます。 これで自分でも割り込み処理を行えそうです。 ありがとうございました。