• 締切済み

H8/OSを用いた割り込みで困っています。

SH2-7045Fを用いて、MTUのTGRAとTNCTのコンペアマッチで割り込みを発生させたいのですが、かなり困っています。まず、MTUのTGRAの割り込みが発生したときの、割り込み関数の割り込み定義を、H8/OSにかいてあった、int_registでやっているのですが、これでいいのですか?あと、開発環境は、秋月でSH2を買ったときについてくるgccを使っていいるのですが、この中には割り込みマスクの設定の関数がないというのを知り、適当にインターネットから拾ったアセンブリ言語で書かれたようなもの(setIntmask())を書いているのですが、プログラムを動かしたとき割り込みを1度しか受け付けないでプログラムがおわらないで、なにかしています。教えてくださいお願いします。

みんなの回答

  • R32C
  • ベストアンサー率39% (115/290)
回答No.1

H8/OS と GDL(gcc developer Lite)など、割り込み関係は 流儀がちがう(という表現が適切かどうか不明)ようで、 どちらかの流儀に従って作ることが必要かもしれませんね。 GDLでは、割り込みハンドラは普通のCの関数で書けますが、 そうでない場合は、割り込みハンドラ特有の記述(たいした記述 ではないですが)を書く必要がありますよね。 その辺はどうでしょうか? 若干気になったのは、setIntmask()を拾ってきて書いたようですが、 環境によって問題ないのかもしれませんが、たまたまぐぐって見つかった setIntmask()は、若干問題があるように思いました。 以下のSetSRRegは問題ないように思います。 http://www2s.biglobe.ne.jp/~NAOTO/acs/sh2/sh2c/sh2r1.h

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • SH7144のMTU割り込みについて

    マイコン初心者です。 現在SH7144の勉強を行っているのですが、MTUによる割り込みが上手くできずに困っています。 開発環境はGCC Developer Liteになります。 下記にソースを示します。 #include<7144.h> void initIO(void) { PFC.PECRL2.WORD = 0x0000; //ポートEの7~0を入出力に設定 PFC.PEIORL.WORD = 0xffff; //ポートEの15~0を出力に設定 } void initMTU(void) { MST.CR2.BIT._MTU = 0; //MTUモジュールスタンバイの解除 MTU0.TSR.BIT.TGFA = 0; //TGFAフラグクリア MTU0.TCR.BYTE = 0x22; //TGRAのコンペアマッチでクリア //PΦ/16でカウント=1562.5kHz MTU0.TMDR.BYTE = 0xC0; //TGRA通常動作 MTU0.TIER.BYTE = 0x41; //MTU0のTGIEAコンペアマッチで割り込み MTU0.TGRA = 1562; //パルス周期設定(1562.5kHz/出力周波数1kHz=1562回) INTC.IPRD.BIT._MTU0G = 15; //割り込み要因MTU0のTGIプライオリティ15 MTU.TSTR.BIT.CST0 = 1; //MTUカウンタ動作開始 } void int_tgi0a(void) { static int d = 1; MTU0.TSR.BIT.TGFA = 0; //TGFAフラグクリア PE.DRL.BIT.B0 = d; //PE0に出力 d = ~d; //dの値を反転 } void main(void) { initIO(); initMTU(); while(1); } プログラムはMTU0のTGIEAコンペアマッチで割り込み、PE0の出力を反転する動作を考えて書きました。 ご教授の程をお願い致します。

  • H8マイコンでの割り込み(シリアルポート入力で)

    マイコン:AKI H8/3048F 開発環境:GCC Developer Lite マイコンとパソコンをRS-232Cケーブルでつないでいます。 ハイパーターミナルを使用して、マイコンを制御したいと考えております。 それで、パソコンのキーボードから入力があった時だけ、割り込みを実行したいです。 割り込みが無い場合は、パソコンでマイコンを制御することができたのですが、割り込みを追加したら、うまくいかなくなりました。 アセンブラを使用せずに、C言語だけでプログラムを完成させたいと思っています。 SCI1からの割り込み処理をするには、どの様にしたらよいのでしょうか? どうか、お願いいたします。

  • マイコンSH-2の割り込みを用いたシリアル通信

    SH7144Fで割り込みを用いたシリアル通信を行っていますが, 途中で割り込みがかからなくなる症状に悩んでいます. 開発環境はHEW上でツールチェインにRenesas SuparH StandardとKPIT GNUSH [ELF]を 組み込んでおり,適宜選んで使っています. 以下,Renesas SuparH Standardで,受信割り込みの場合に限って書かせて頂きます. 少々長くなりますが状況をご説明致します. 最初にSCI1回りの設定を適切に行い,割り込みレベルを15とした後, set_imask(0)で割り込みレベルを0として割り込みがかかるようにしています. 受信割り込みがかかるとINT_SCI1_RXI1に飛び, _UBYTE c = SCI1.RDR; SCI1.SSR.BIT.RDRF = 0; と直ちにした後,cの内容をバッファに入れ,戻っていますが,一文字受信しただけで 割り込みがかからなくなります.(_UBYTEはtypedefine.hでunsigned charとしています.) 相当悩んだ挙句,INT_SCI1_RXI1の末尾に, set_imask(0); を入れてやると連続して割り込みがかかり,うまく受信できるようになっています. ハードウェアマニュアルを読めば,割り込みがかかるとSRレジスタは退避され, SCI1の割り込みレベル15の内容がSRレジスタのI0~I3に書き込まれる,とあります. 当然,割り込みが終われば,退避された内容がSRレジスタに戻るので割り込みマスクは 0に戻るもの・・・と解釈していますが,余りにも当たり前なのかハードウェアマニュアルには 明記はされていません.もしかしたら元に戻っていないのでは・・・と,上記のようにいちいちに 割り込みマスクを0にする手続きを追記すると動いている,と言う状況です. 因みに上記の状況はKPIT GNUSH [ELF]を選んだときにも同じです. 更には,送信割り込みのときも上記と同じくset_imask(0)を入れてやると動きます. そこで質問ですが, 1.SRレジスタは割り込みが終われば元の内容に戻ると解釈していますが,   これで合っているでしょうか. 2.上記1で元に戻るのだとしたら,なぜいちいちset_imask(0)をしてやらないといけない   状況になっているのか・・・考えられる原因をお教えください. 雑多な説明で申し訳ございませんが,どうぞ宜しくお願い致します.<(__)>

  • h8/3052 GDB-stub上でのプログラムの実行 ITUタイマ割込みの使用について

    現在h8/3052でITUタイマを利用して20msecごとに割り込みがかかるようにするプログラムを作成していますが、割り込みに関して動作が確認できません。デバッグ環境を整えるためにターゲットにはあらかじめGDB-stubを書き込んであります。 実際に作成しているプログラムの割込みの部分は、 //割込み処理関数 pragma interrupt void int_imia0(void) //割り込み関数 { extern volatile unsigned int count; count ++; ITU0.TSR.BIT.IMFA = 0; } で割り込みが行われたときの処理を行い。 //メイン関数内 EnableInterrupt(); //割り込み許可 StartITU0(); //タイマスタート while (1){ AD.CSR.BIT.ADST = 1; /*変換スタート*/ while (AD.CSR.BIT.ADF == 0); /*変換終了待ち*/ data[c] = AD.DRA >> 6; /*下位へ6ビット分ずらす*/ data[c] = data[c] & 0x3ff; /*上位6ビットクリア*/ time[c] =(count * 2000000) + (ITU0.TCNT * 32); /*A/D変換処理時間の算出*/ if(time[c]>20000000) { bleak; } } のようにして、ここで20msecごとに割り込みがかかるように設定しています。 で、出力ファイルの //MAPファイル Name Origin Length Attributes vectors 0x00220000 0x00000100 r rom 0x00220100 0x00007f00 xr ram 0x00228000 0x00007000 xrw stack 0x0022f000 0x00001000 rw vectorアドレス ITU0割込みベクタアドレス(0x220060) 0x00220060 0x4 LONG 0x22020a DEFINED (_int_imia0)?<code 340> (_int_imia0):<code 340> (_start) として、外部RAM領域に設定したvectors領域のベクタ領域に割込み関数のアドレスが入るようにしています。 実際に動かすと、割込み関数でブレークポイントを設定しても割り込みがかからずにプログラムが動かなくなってしまいます。(どこかに飛んでいってしまっている。) ここで質問なのですが、GDB-stub上でプログラムを動かす場合に、 ・割り込みがかかった場合のベクタアドレスはGDB-stub側で設定しているベクタアドレス(内部ROM0x000060)に飛ぶようになってしまっているのか。 が、気になっています。

  • dos.hについて

    今、私の使っているパソコンはOSがwindowsXPで、コンパイラはBorlandBCCです。 大学の図書館で借りた、かなり古いと思われる(平成4年に第1刷発行で、この本自体は平成5年の第4刷発行)c言語のプログラムの本を読んでいるのですが、その中のグラフィックを扱う部分で、 <dos.h> のヘッダの中に outp() outport() int86() の定義がされている とあるのですが、本に書いてある通りにコーディングしてみても<dos.h>をインクルードしても、これらの関数は定義されていないみたいなんです。 これは本が古すぎて、現在は変わっているからなんでしょうか? また、変わっているなら、これらの関数は、現在はどんな関数と置き換わっているんですか? ちなみに、私はOSに関しての知識はそれ程持ち合わせてはおりませんので。 こんな私に誰かご教授お願いいたします。

  • H8/3048F IRQポートを使った外部割込みについて

    秋月電子のH8/3048Fマイコンボードを購入し、C言語による組み込みプログラムの演習を行っていて、マイコンボードのIRQ端子を使った外部割込みを実装しようとしてつまずいてしまいました。 メインループでLED点灯などの処理を行い、タクトスイッチの押下があったら別の処理を割り込ませ、またもとの処理に戻るという外部割込み処理を行いたいのですが、うまくいきません。 今おきている問題としては、 (1)電源の投入して、メインの処理(LED点灯)が行われる前になぜか一度IRQ割り込みが発生し、別処理が行われ、その後メインの処理を行う。 (2)IRQポートには立下り割り込み処理を行いたいので、プルダウン抵抗回路を組み、通常状態では、 IRQポート→チャタリング防止用のシュミットトリガ74LS19(NOT回路が含まれている)→10KΩの抵抗器→GND という回路でHIGH状態からタクトスイッチによる押下が行われたら、 0.1μFのコンデンサ→+5V という回路につながり、LOWになって、立下りエッジが検出され、割り込み処理が行われるはずだが、タクトスイッチを押下してもなかなか反応せず、5~6回押さないと割り込みが行われない。 (3)割り込み処理実行後、元の処理に戻らない。(このとき、タクトスイッチ押下による割り込み処理は再度受け付けてくれる) の3点です。 C言語関連のH8マイコンの教材は無く、Web上の情報でしか勉強していないので、必要な知識が欠けているかもしれませんが、どなたかお知恵を貸していただけないでしょうか? 当方のH8/3048Fによるプログラミング暦は1ヶ月ほどで、LEDの制御、外部スイッチ入力による処理等基本的なことは出来ていると思います。 メイン処理と割り込み処理のソースコードを載せておきます。 void int_irq0() //割り込み処理関数 { /* lcd_init(); lcd_locate(0,0); lcd_print("ワリコンダYO!"); wait(500); lcd_locate(0,0); lcd_print("モトニモドルYO!"); */ P5.DR.BIT.B0 = 1; wait(300); P5.DR.BIT.B0 = 0; wait(300); INTC.ISR.BIT.IRQ0F = 0; //ISRフラグをクリアする } void main(void){ //char moji[16] = "AKI-H8"; unsigned int rand_seed = 100; P1.DDR = 0x00; P5.DDR = 0xff; PB.DDR = 0xff; INTC.ISCR.BYTE = 0; INTC.ISCR.BIT.IRQ0SC = 1; //立下りエッジで割り込み検出 INTC.IER.BIT.IRQ0E = 1; EI; srand(rand_seed); timer_init(); /* タイマーの初期化 */ lcd_init(); /* 液晶表示器の初期化 */ lcd_locate(0,0); /* カーソル位置の指定 */ lcd_print("スイッチオセ!"); /* 文字列の表示 */ while(1){ //disp_data(); led_randset(); wait(100); led_allclr(); wait(10); } /* 無限ループ */ }

  • 割り込みのカウントの仕方

    c言語、PICともに素人です。 あるサイトのプログラムで、割り込みを使いLEDを点滅させるというものがありました。 割り込み時毎にLEDへの出力を反転させているだけです。 しかし、これだとLEDの点滅が速いのでもう少し遅くしようと、割り込み10回で出力を反転させるようなプログラムを組みました。 #include "pic.h" #include "delay.h" __CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & CP_OFF); int a; void main(void) {  GIE = 1;  T0IE = 0;  T0CS = 0;  PSA = 0;  OPTION_REG |= 0x07;  TMR0 = 0x00;  TRISA = 0x00;  TRISB = 0x00;  a = 0;  T0IE = 1;  while(1); } void interrupt peko(void) {  if(T0IF)  {   if(a==10)   {    T0IF = 0;    PORTA ^= 0xff;    PORTB ^= 0xff;    a=0;   }   else   {    a++;   }   return;  } } aという変数をおいて、最初a=0にしておきます。 割り込みが発生するたびにaに+1していき、aが10に達した時処理をし、aを0に戻す。 これで点滅速度が1/10ぐらいになるだろうと思ったのですが、全く変わりません。 点滅はします。 一体何が違うのでしょうか。 ご教授お願いします。

  • 割り込みベクタに飛んだ場合必ず”OSIntEnter();”という関数は使わないといけない?

    今、H8S2368のために書かれたプログラムを見ているのですが、このプログラムではuC/OSというプログラムの関数である"OSIntEnter();"という関数が出てくることがわかりました。それで、OSIntEnter()関数というのが現在のソースプログラムの中でどのように使われているのかを、全ソースに対して検索をかけてみたところ、必ずと言っていいほど割り込みベクタのプログラムである下記のようなプログラムで使われていることがわかりました。 __interrupt(vect=22) void INT_IRQ6(void) { OSIntEnter(); OSSemPost(CmxInt); OSIntExit(); } たぶん、割り込みが発生して、その割り込みの種類の割り込みベクタに飛ぶときにこの”OSIntEnter()”というのを使わなければならないのだろうと推測しているのですが、 もし、割り込みベクタで”OSIntEnter()”を使わなかった場合、どのような問題がおきるのでしょうか?

  • H8Sで割り込み発生時の飛び先アドレスがRAM上にある場合の割り込み関数の記述方法

    ルネサスのマイコンH8Sのプログラムを組んでおります。 プログラムの構成がBoot部分とアプリケーション部分に分かれており、 Bootはアドレス0番地から、アプリは3000番地以降の領域を使用するようになっています。 完成されたBootを使用してアプリケーションのプログラムを組まなければならなく、また、Bootは変更できないことになっています。 このBootの中のベクターテーブル上で、割り込みが発生した場合の飛び先のアドレスがRAM上になるように設定してあります。 このため、アプリケーションソフトでは、 割り込みが発生した場合のRAM上の飛び先に FLASH ROM上の指定したアドレスにジャンプする命令を書き、 FLASH ROMのジャンプ先には、実行したい関数を書きたいのですが、 (1)RAM上の特定のアドレスからFLASH ROM上の指定したアドレスにジャンプさせる方法。 (2)FLAH ROM上の指定したアドレスに関数を記述する方法。 を知りたいのですが、 どなたか教えて頂けないでしょうか? 開発環境はHew4 言語はC言語を使用しております。 私自身が理解不足であるため質問内容が伝わりにくいかと思いますが、 宜しくお願い致します。

  • C言語の関数(if文やfor文を含む関数)の定義の仕方

    C言語の関数(if文やfor文を含む関数)の定義の仕方 int WINAPI WinMain(HINSTANCE hI,HINSTANCE hP,LPSTR lpC,int nC){ ●● } ↑上記のような形式のウィンドウアプリケーションの場合、 関数の定義はint WINAPI~の前にしておくべきなのでしょうか? 関数の中にif文やfor文を入れようとすると「関数定義のようですが、パラメータ リストがありません。外見上の本体をスキップします。」というエラーが出てしまいます。 int WINAPIの中で定義しようとするとそれはそれで「ローカル関数の定義が正しくありません」というエラーが出てしまいます。 詳しい方がいたらアドバイス願います。 ※関数を使わずにプログラムを組んだことはあるのですが、関数の定義に初挑戦しようとしたところ見事にわけが分からなくなってしまいました。