ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

H8マイコンコミュのh8/3069割り込みの質問です

  • mixiチェック
  • このエントリーをはてなブックマークに追加
どこに書いていいのかわからずトピック作らしていただきました。

現在H8/3069F にmes(ver.2.3r18)を乗せているのですが、
割り込み処理で困っています。

?割り込みハンドラの設定のしかた
?割り込みマスクビットの設定のしかた

この2点わかる方いましたらよろしくお願いします。

自分の作ったプログラムを載せたほうがわかりやすいのでしょうか?

コメント(19)

割り込みにもいろいろあるので

>自分の作ったプログラムを載せたほうがわかりやすいのでしょうか?
ではありますね。

まずは何をしたいのかを書いておくと回答もつきやすいかと思います。
漠然とした内容ですみません。
やりたいことは
「LEDの点灯から割り込みでLEDを消す」
というプログラムです。

#include <mes2.h>
#include <h8/reg3067.h>



#pragma interrupt //割り込みハンドラのつもり
void int_handler(){
load_segment(17); //ベクタテーブル、17はIRQ5の設定
P4DR = 0x00;   //P4に0入力(消灯)
sleep(5000);   //5秒間続ける

ISR &= ~0x10; //割り込みフラグクリア
}

#define DI asm("orc.b #0xc0,ccr") //割り込みマスクビット設定(割り込み許可)
#define EI asm("andc.b #0x3f,ccr") //割り込みマスクビット設定(割り込み禁止)
int main(){

set_handler( 17, int_handler ) ;//割り込みハンドラ


EI; //割り込み禁止
ISCR |= 0x10 ; //入力の立下りエッジ割り込み要求発生
IER |= 0x10 ; //IRQ5の割り込みを許可
P4DDR = 0xff ; //ポート4を出力モードに設定
DI; //割り込み可
while(1){
P4DR = 0xff;   //P4に1入力(点灯)
sleep(1000);
}
}


プログラムは以上になります。
これを実行してうまくいかなかったのですね?
データシートとかまだ見てないので(←探せよ!)細かいところはなんともですが、気になる点がいくつかあります。

・割込みハンドラの本体はMES内部にあり、ユーザープログラムにはそこから転送されるだけなので、interrupt修飾は不要。というかつけてはいけない。

・割込みハンドラ内でシステムコールを呼ぶとまずいことになる。割込みハンドラはフラグ立てに専念し、ユーザーループ内で実際の処理を行うとよい。

あと、割込み許可にDI(Disable Interrupt)って名前をつけるのはいかがなものかと思いますが^^;
shigさんありがとうございます!

コンパイルは通るのですが実行しても割り込みできずに
ずっとLEDついたままになります。

>割込みハンドラ内でシステムコールを呼ぶとまずいことになる。割込みハンド
>ラはフラグ立てに専念し、ユーザーループ内で実際の処理を行うとよい。

これは

#pragma interrupt //割り込みハンドラのつもり
void int_handler(){
load_segment(17); //ベクタテーブル、17はIRQ5の設定
P4DR = 0x00;   //P4に0入力(消灯)
sleep(5000);   //5秒間続ける

ISR &= ~0x10; //割り込みフラグクリア
}

ここから

P4DR = 0x00;   //P4に0入力(消灯)
sleep(5000);   //5秒間続ける

この部分を抜いて別の場所に書くとい言うことでしょうか?
>この部分を抜いて別の場所に書くとい言うことでしょうか?
問題があるのはsleep()なのでそこをなんとかしなくちゃなのですが、置き換えるにしてもプログラムの意図がわかんないんですよ。
LEDを点灯させといて、irq5が立ち下がったら消灯させる、永遠に再点灯はしない、ってことでいいんでしょうか?
となると「5秒間続ける」の意味が?ですが。
P4DR = 0x00;  
sleep(5000);

これで (P4DR = 0x00;)って出力を5秒(sleep(5000)=5秒)続ける
って意味になります。

wait関数と同じです。

やりたいのはP4に繋がっているLEDを、IRQ5に繋がっているタッチセンサを押した後、
5秒消灯さして、また点灯させるというのがしたいです。
andc.b #0x3f,ccrでccrのiビットが0になって、
割り込みが許可になるのでは?
MESはマルチタスクのOSですので、msオーダーでのレスポンスが必要なければ、
センサ入力を常に監視してLEDをON/OFFさせるだけのタスクと、メインのタスクを
別々に作って、同時に実行させたらスマートだし無駄にCPUを使わなくて良いかと思います。(割り込み中で時間待ちはCPU資源の無駄づかいだと思います)
どうしても割り込みを使いたい場合はドライバーとしての実装もなかなか綺麗です。
ちぃと気になったんだけど、

タッチセンサってチャタリング対策しなくて大丈夫なんですかね?
>>タクミさん
レス感謝です。
#define DI asm("orc.b #0xc0,ccr") ;
これで許可で合ってるのでしょうか?

>>hajimeさん
同じくレス感謝です。
マルチタスクというものをプログラムしたことないのでタスクの設定というのがまったくわからない状態です。
割り込みと同時に試してみたいと思います。
もしよろしければお勧めの参考書、サイト教えていただけないでしょうか?

>>shigさん
初めてチャタリングという言葉を聞いて調べてみたのですが、対策必要かもしれないですね。

今回はとりあえず割り込みとマルチタスクの設定やってみたいと思います。
>これで許可で合ってるのでしょうか?
名前の通りDisable(禁止)みたいですね。

マルチタスクについてですが、MESはマルチタスクOSだけどスレッドAPIは持ってないのでプロセスで分割して実現することになります。
参考書とかサイトとか(そのものずばりは)見たことないなあ。なんか書いておいたほうがいいのかな。

割込みベースでプログラミングするなら、タイマ割込みも使ってそこで時間管理したほうがいいと思います。タッチセンサによる割込みがかかった時点で消灯すると同時にタイマを走らせ、タイムアップしたら点灯するようにする、とか。

わたしはこのテのモノを組むときは、チャタリング対策の意味もあって敢えてメインループ内にすべてを記述してます。人間による入力は充分に遅いので、数〜数十ms感覚でピン状態の変化を複数回チェックするようにするとうまくいきます。他のことも同時にさせたかったら上記のようにプロセス分割してしまえばOKです。
>もしよろしければお勧めの参考書、サイト教えていただけないでしょうか?
参考書、サイトではないですが、

例えば

pro1

int main()
{
P1DDR = 0x00;
P4DDR = 0xff;

for(;;) {
 while(P1DR&0x01) continue; // 入力ON待ち
 sleep(10);
 if(P1DR&0x01) continue;
 sleep(10);
 if(P1DR&0x01) continue;
 P4DR = 0x00;   //P4に0入力(消灯)
 sleep(5000);   //5秒間続ける
 P4DR = 0xff;   //P4に1入力(点灯)
 while((P1DR&0x01)==0) continue; // 入力OFF待ち
 }
}

みたいなのを作って、shellから
>pro1&
で起動すれば、pro1はプロセスとして常駐して
>
と戻るので、他の処理をするpro2をさらに
>pro2&
で実行すれば、pro1とpro2(とshell)が同時実行になります。
>ps
で確認できます。
↑MES2の場合は実行ファイルはpro1.elfとかになるので
>pro1.elf&
でした。
拙作の拡張shellなら拡張子なしでも実行できますよん♪
http://www.esprix.net/~shig/mes.html

と宣伝... f^^;
皆様すいません

上でマルチタスクにも挑戦したいと言っていましたが、
しばらくは割り込みにしぼって勉強していきます。

同時にやるには知識なさすぎなのでまずは当初の予定通り、
割り込みからやっていきたいと思います。
一応IRQ割り込みできました!
プログラム載せときます。

できなかった最大の理由がポートの設定の間違いという
恥ずかしいことでした><

ただチャタリング対策がうまくいかず、実行すると
プログラム内のonoff変数が2,4,6,8のように偶数になることが多いみたいです。

ありがとうございました!

//LEDの点灯、消灯を切り替えるプログラム

#include <mes2.h>
#include <h8/reg3067.h>

int onoff ; //LED動作用変数

void ioinit(void){
P4DDR = 0xff; //P4出力
P9DDR = 0x00; //P9DDRリセット(IRQ5がP9にあるためのリセット)

}

#pragma nosave_low_regs //割り込みハンドラ(mesのHPのシステムコールの欄に記述されてる)
void int_handler(){
volatile long j;

load_segment(17); //ベクタテーブル、17はIRQ5の設定
ISR &= ~0x20; //割り込みフラグクリア

onoff++;
for(j=0;j<20000;j++); //チャタリング対策
}


int main(){

set_handler( 17, int_handler ) ; //ハンドラセット

ioinit();

int_disable(); //割り込み禁止(mesのHPのシステムコールの欄に記述されてる)
ISCR |= 0x20 ; //入力の立下りエッジ割り込み要求発生
IER |= 0x20 ; //IRQ5の割り込みを許可
int_enable() ; //割り込み可(mesのHPのシステムコールの欄に記述されてる)


while(1){

if(onoff % 2 == 0){
P4DR = 0xff;
}

else if(onoff % 2 == 1){
P4DR = 0x00;
}

printf("onoff=%d\r",onoff); //状態確認のために出力

}

}
うまくいってよかったですね。

ちなみに時間待ちでチャタリングは取れません。
例えば10ms間隔で入力を2、3回読んで、全て同じ値だったら跳ねている期間が過ぎたと言う事で確定するのがチャタリング処理です。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

H8マイコン 更新情報

H8マイコンのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング