• ベストアンサー

割り込みの入り方。考え方。

今研修で秋月のH8のキットを使って勉強をしているのですが 割り込みについて理解できないところがあります。 タイマ割り込みなどの割り込みとは メインの関数をよんでいる時に割り込んで今まで実行していたのに変わって実行されるわけですよね? そのタイミングなんですが ファイルを実行させるとソースの上から読むってのはわかるんですけど 例えば5行目の途中とかでも割り込みが行われるんですか? つまり行単位で実行していてその間にはいってくるのか 行の中の単語?をよんでる最中に割り込んでくるのか。。。 知識が無いためうまく説明できませんがわかりますでしょうか? よろしくおねがいします

質問者が選んだベストアンサー

  • ベストアンサー
  • Qwerty-36
  • ベストアンサー率25% (58/226)
回答No.5

他の回答者が言っていることを要約するだけですが CPUは機械語(アセンブリ言語)で書かれたプログラムを実行しています。 せっかくH8マイコンの動くボードをお持ちなのですから、アセンブリ言語とはどういうものか、理解しましょう。 割り込みについては、その理解、知識が無い方には説明は非常に難しいです。

fen_ri
質問者

お礼

アドバイスありがとうございます。 アセンブリも少し勉強したいと思います。

その他の回答 (4)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.4

> こうゆうプログラムにタイマかなんかで割り込むとき > 上もしくは下の行の実行が終わった時に割り込まれるのか > > 上もしくは下の行の実行が終わって次の行を読み始めた途中でも割り込みが発生するのかどうかって事です。 この場合は、行の途中でも割り込みが入ります。 秋月のどのボードを使っているのかわかりませんが、コンパイラにGCCを使っているのであれば、 h8300-hms-gcc -S -mh オプション ファイル名 とすれば、アセンブリ言語のソースが出力されるので、それを見るとよくわかります。 まず、代入すべき値(ここでは0x01や0xfe)をレジスタに読み込んで、その値を出力ポートに書き込んでいるはずです。 P5.DR.BYTEの定義次第では、さらに複雑な命令に展開されているはずです。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

詳細は補足していただくのを待つとして、わかる範囲で書いてみます。 H8/300Hの場合、ほとんどの命令は不分割ですが、一つだけ例外があります。それはEEPROM命令でワード単位の転送を行う場合です。この命令に限り、命令の実行が終わる前でも割り込みが入り、命令が中断されます。 それ以外は、1つの命令の実行が終わるまで、割り込みは入りません。 C言語での行単位の話であれば、C言語の場合、コンパイラが受け付けてくれる限り(翻訳限界まで)、同じ行にいくらでも式をかけますし、たった一つの代入しかしていないように見えても、実は多くの命令が実行されている場合があります。 機械語レベルで、命令が複数になれば、当然その間に割り込みが入ってきます。割り込みが入ってまずいのであれば、明示的に割り込みを禁止する必要があります。

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.2

割りこみは機械語の一命令語の終了のタイミングで行われます。 割りこんだ側が戻ってきたときの先頭番地を保存します。 割りこみ処理が終わると先ほど保存した次実行の先頭番地から続けて何事も無かったように 実行が再開されます。 こう言う関係ですからお同じデータエリアを2つのプログラムが共有することはまずありえません。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

> 例えば5行目の途中とかでも割り込みが行われるんですか? 5行目というのがよくわからないのですが、アセンブリ言語でプログラムを書いていますか?それともC言語ですか?

fen_ri
質問者

補足

すいません。5行目とはたとえで何でもないです。 ちなみに言語はCです。 用は。 void main(void){ P5.DR.BYTE =0x01;   (上) P5.DR.BYTE =0xfe;   (下) } こうゆうプログラムにタイマかなんかで割り込むとき 上もしくは下の行の実行が終わった時に割り込まれるのか 上もしくは下の行の実行が終わって次の行を読み始めた途中でも割り込みが発生するのかどうかって事です。 言葉、知識が足らなくてすみません;;

関連するQ&A

  • 割り込み処理のシミュレート

    現在開発している組み込み系システムのシミュレートをVCで行いたいと考えています。 組み込み系のシステムは簡単に言うと、 普段はメインループでくるくる回っており、1ms毎にタイマ割り込みが発生し、変数の値を書き換え、メインループではその変数の変化によって何か処理を実行するというものです。 このようなシステムをVCでできるだけ同じようにシミュレートするため、マルチスレッドを用いようと考えているのですが、以下の性質を実現することは可能でしょうか? ・メインスレッド実行中はタイマ割り込みスレッドは割り込み可能。 ・タイマ割り込みスレッド実行中はメインスレッドは割り込んでこない。 ・メインスレッドで特定の区間タイマ割り込みスレッドの割り込みを禁止できる。 ・高速シミュレートを行いたいため、割り込みの禁止などはできるだけ低負荷で行いたい。(ミリ秒単位だとNG) ・複数の割り込みスレッドがある場合、各スレッドごとに割り込みレベルを設け、このレベル以下を割り込み禁止など行いたい。 スレッド以外の実現方法などあればそちらもご教授願いたいです。 よろしくお願いします。

  • AKI-H83048で割り込みを使用してLEDを点滅させたいのですが、、、、

    はじめまして、組み込みソフト超初心者です。 割り込みタイマを使用してLEDを特定時間点滅させる、ということを行いたいのですが、コンパイルができず、頓挫しております。どなたか、アドバイス頂けませんでしょうか。 ・開発環境はAKI-H8 3048 ・割り込みを使用してLEDを点滅させるということを目的にCでソースをコーディングしています。 ・巷の参考書など参考にしてmain、割込関数、コーディングしました。 ・コンパイラはAKI-H8マイコンキットについてきた専用CコンパイラCC38Hを使用しています。(統合開発環境はありません) 上記の条件でコンパイルすると、interruptがイリーガルとエラーが出ます エラーの出ているコードは #pragma interrupt itu0_int(vect=24) の部分です。 参考書で、interruptはコンパイラによって使用できないようなことも読んだのですが、どうすればコンパイルできるのでしょうか、また、何が足りないのでしょうか なにぶん初心者なもので、正直質問の的が絞れていないのかも解らないのですが、とにかくまず動かしたいと思い質問させて頂きました。 同じ開発環境の方が居られましたら有難いです。 何とぞよろしくお願い致します。

  • 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)に飛ぶようになってしまっているのか。 が、気になっています。

  • IC16F1829でのCCPモジュールについて

    PIC16F1829でのCCPモジュールを使用した、パルス幅のキャプチャについて 割込み関数を用いたら、mainループ内でCCP*IFを検知しません。状況: CCPモジュールを用いて、パルスの幅を計測しようとしています。CCP単独での動作では、パルス幅を計測できました。 ここでの「単独」とは、割り込み関数を用いないmainループ内での処理です。 //「単独」での仕様 // (1)CCP2モジュールでPWMパルスを発生する (2)上記パルスをCCP1で立下がり、CCP4で立上がり検出する (3)上記の値の差を計算 (4)I2C通信でLCDに表示 これで、タイマ1の分解能を1usに設定し、パルスのOFF時間を計測できました。 問題: PICにラインカメラを接続し、カメラの出力パルスOFF幅を計測したいのですが できません。 原因: mainループ内 if(CCP1IF){ } に処理が入らない。 質問: なせCCP1IFを検知できないのでしょうか。 割込み関数を入れると、検知できないようになってしましいます。 何か競合するのでしょうか。 PICでは割込み関数の処理が終わるまでは、ほかの割込み禁止なはずなので 下に書いてある、フローチャート通りにプログラムが動くはずなのですが・・ 私の力不足で、うまく動作しません。 後閑さんの本やPIC16F1829のデータシートも見ましたが原因がわかりません。 よろしくお願いします。 仕様(フローチャート): 概要 割込み関数は ・タイマ0 (CCP2のパルスカウント) キャプチャした値の計算とシリアル送信を行う ・タイマ4 (20ms周期でリセットパルスを生成) メイン関数は ・CCP1で立下りエッジ検出 ・CCP4で立上がりエッジ検出 ****** タイマ0の割込みは約13msです。 タイマ4は20msです。 時系列で言うと (1)プログラムスタート~タイマ0割込みまで(0~13ms) main関数が走り、パルスのエッジをキャプチャする (はずですが、現状CCP1IFを検知できません) (2)タイマ0割込み中(13~19.9ms) キャプチャの値の計算とシリアル送信 (3)タイマ4割込み発生(20ms) リセット信号と全ての値のクリア

  • 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); } /* 無限ループ */ }

  • VC++2010 画面なしのアプリケーション作成

    VC++2010 画面なしのアプリケーションを作成したいんですが、VC++2010で作成する方法が調べても出てこなかったので質問させていただきました。 環境はWindows7で開発環境はVisualStudio2010 使用言語はC++です。 やりたいこととして、マイコンみたいにプログラムを組みたいと思っています。 メイン関数から始まって Wihile(1) ;で待機し SetTimer(1,1000,NULL)などのタイマ割込みで処理を行う形です。 よろしくお願いします。

  • H8で自作マウス

    秋月電子の『AKI-H8/3048F USB開発キット』を使って、ボタンを押すとポインタが動くマウスのようなものを作ろうと思っています。 ボタンを押すと、今ポインタのある場所から少し動くという風にしたいのですが、どういう関数を使ってデータをパソコンに送ればいいのでしょうか?

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

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

  • 2度目の投稿となります。

    2度目の投稿となります。 現在、社員研修でPIC18F2550を使ったプログラミングを行っているのですが、下記内容についてうまく動作しません。 大変恐縮ですが、原因についてアドバイス頂けますと幸いです。 作成環境はMPLAB V8.36、MPLAB C18コンパイラV3.33 です。 <質問内容> ◎タイマ1がうまく動作しない。 やりたい事は、  (1)タイマ0(8bit)を使い割り込みを発生させ、ポートから信号ON/OFF(PWM信号を出したい)。  (2)タイマ1(16bit)を使いCCP1/2のコンペアマッチ割り込みを行ない、CCP1ポートからPWM信号ON/OFF(サーボモータの動作用PWM信号を出したい)。 (1),(2)を同時進行で動作させたい、というものです。 シミュレーションで確認したところ、タイマ0/1のカウントアップ動作自体は確認できているのですが、タイマ1が8bitのところでオーバーフロー?して、タイマ0と同時に0にリセットされてしまいます。 以下に作成コードを掲載します。 --【以下、コード抜粋】-- //===《初期設定》=== //---<ヘッダーファイル>--- #include<p18f2550.h> //---<コンフィグレーション>--- //---<関数宣言>--- //---<割り込みの定義関連>--- //===《動作プログラム》=== //---<メイン関数>--- void main() { ioport_settei(); //サブルーチン「ioport_settei」実行(入出力ポート初期設定) interrupt_settei(); //サブルーチン「interrupt_settei」実行(割り込み初期設定) tmr_ccp_settei(); //サブルーチン「tmr_ccp_settei」実行(タイマ&CCPモード初期設定) while(1) //繰り返し(ずっと繰り返す) { } } //---<サブルーチン>--- void ioport_settei(void) //[入出力ポート初期設定] {省略} void interrupt_settei(void) //[割り込み初期設定] { INTCONbits.GIE = 1; //グローバル割り込み設定:許可 INTCONbits.PEIE = 1; //周辺割り込み設定:許可 INTCONbits.TMR0IE = 1; //タイマ0割り込み設定:許可 PIE1bits.TMR1IE = 1; //タイマ1割り込み設定:許可 PIE1bits.CCP1IE = 1; //CCP1割り込み設定:許可 PIE2bits.CCP2IE = 1; //CCP2割り込み設定:許可 } void tmr_ccp_settei(void) //[タイマ&CCPモード初期設定] { TMR0H = 0; TMR0L = 0; TMR1H = 0; TMR1L = 0; T0CON = 0b11001000; //タイマ0設定(有効,8bit,内部クロック,プリ1倍) T1CON = 0b10000001; //タイマ1設定(有効,16bit,内部クロック,プリ1倍) CCP1CON = 0b00001001; //CCP1設定(Compare mode,RC2=0,割り込み発生) CCP2CON = 0b00001011; //CCP2設定(Compare mode,スペシャルイベントトリガ,割り込み発生) CCPR1 = 3750; //CCP1 Duty値初期設定(PWM(ON時間)=1.5ms…ニュートラル位置) CCPR2 = 50000; //CCP2 Duty値初期設定(PWM(周期)=20ms) } //---<割り込み処理関数>--- #pragma code void isr(void) { if(INTCONbits.TMR0IF == 1) { INTCONbits.TMR0IF = 0; } } となります。 大変恐縮ですが、原因が判る方がいらっしゃいましたら、ご教示のほどよろしくお願い致します。

  • エクセルVBAでms単位でのタイマ(wait)

    エクセルVBAで制御をやりたいと思っています。 描画を切ったらそれなりの実行速度が出るのは確認済みなのですが、実行環境のスペックによってかなりばらつきがあるので、ちゃんとしたタイマを実装したいと思っています。 秒単位のスリープ的なものは検索して何件か見つけたのですが、ms単位でのwaitは見つかりません。 何かいい方法をご存じないでしょうか。 PS: 多重ループを毎回はさんで負荷をかけて実行速度を下げるやりかただと、環境依存が強すぎました。 Pentium4でちょうどいいのウェイトに使ってた関数がcore i7だと瞬殺だったりで、これは使えないなと。

専門家に質問してみよう