« エレキジャックNo.4の付録基板 | メイン | 7-8 課題8 割り込み処理 ~その2~ »

はてなブックマークに追加   7-7 課題7 割り込み処理 ~その1~

課題6のCソース・ファイルとHEXファイルはこちらです【LZH】

■ 課題7

 RIGHT,UP,LEFTのlEDでは1秒間隔で●●●●と○○○○の点滅を行います。
 一方、割り込み処理を使って、DOWN_LEDは0.1秒間隔で○○○●と○○○○の点滅を行います。
 DOWN_LEDとほかのLEDでは点滅間隔が違う、割り込み処理の課題です。


ex7-7.gif

// ex7-7_warikomi.c
// PIC16F84A用
#include<16f84a.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)

#byte  RA=5
#byte  RB=6
 #bit IRSIG=RA.2
 #bit TACTSW=RA.3
 #bit DOWN_LED=RB.0
 #bit UP_LED=RB.2
 #bit RIGHT_LED=RB.1
 #bit LEFT_LED=RB.3
int led_data,wcount;
// 1/20(MHz)*4*256*195=9.8304ms
//  9.8304ms*10=0.09830s=0.1s

#INT_RTCC
timer0_led_flash(){
  set_timer0(61); //255-61+1=195
  wcount--;
  if(wcount==0){
    led_data=0x01-led_data;
    DOWN_LED=led_data;
    wcount=10;
  }
}

main()
{
  set_tris_a(0x1f);
  set_tris_b(0x00);
  setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);

  set_timer0(61);
  wcount=10;
  led_data=0;
  enable_interrupts(INT_RTCC);
  enable_interrupts(GLOBAL);

  while(1){
    RIGHT_LED=UP_LED=LEFT_LED=1;
      delay_ms(1000);
    RIGHT_LED=UP_LED=LEFT_LED=0;
      delay_ms(1000);
  }
}

■割り込みとは・・・

 読書に没頭しているとします。読み進み、山場を迎えた頃に、「りりーん」と電話がかかってきてしまいました・・・。無視もできないので、仕方なく出ると「プルトニウムがお買い得ですよ。」(^^;)

 メインに動いているプログラムに対してなんらかのタイミングで別の処理を行うことを「割り込み」といいます。割り込み要求が入るとメイン・プログラムに優先して実行されます。この割り込み処理があることで、PICの能力は飛躍的に向上していますが、一番わかりにくい部分であると思います。
 PICでもいくつかの割り込みが用意されています。ここではよく使うタイマ割り込みを使います。

■割り込み間隔

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);//timer0初期化

 RTCC_INTERNAL:クロックは内部クロックを使う指定です。
 RTCC_DIV_256:プリスケーラ値を256にします。

 PIC赤外線受信ボードでは20MHzのセラロックを接続していますが、これを内部クロックとしてそのまま使います。20MHzで駆動すると、

   1/20MHz=0.05μs:1パルスの時間

 内部ではこの4倍の時間(式の×4倍)がかかるので、

   0.05μs×4=0.2μs:

 PIC内部にあるプリスケーラ=分周器はパルス・カウントを指定の回数積算してから出力する働きがあります。プリスケーラが256とすると、256回パルスをカウントして「1回」とすることになります。したがって、

   0.2μs×256=51.2μs

 これをtimer0でカウントして10msにするには、

   10ms/51.2μs=195回

となるので、timer0で195回カウントして割り込みをかければ10msを得ることができます。timer0が逆算カウンタなので、

  255-195+1=61

がtimer0にセットする初期値となります。+1するのは0の分があるからです。

■割り込みのまとめ

 10msを得るための割り込み間隔の計算方法は・・・・

   1/クロック周波数×4倍×プリスケーラの値×(255-タイマ初期値+1)

    クロック周波数:20MHz
    プリスケーラ値:256
    タイマ初期値:61
の場合は、

   1/20(MHz)*4*256*195=9.8304ms

となり、9.83msごとに割り込みがかかります。

■割り込みを利用したプログラミング

#INT_RTCC              //timer0割り込み処理を使うときはまずこれを書きます
timer0_led_flash(){         //この部分の関数名はなんでもよいのでつけます
  set_timer0(61);          //タイマー初期値です:255-61+1=195
  wcount--;
  if(wcount==0){          //カウンターを減らして、10回の時にledの点灯消灯します
    led_data=0x01-led_data;   //0x01と0x00を繰り返します。
    DOWN_LED=led_data;     //DOWN_LEDの点灯処理
    wcount=10;           //9.8304ms*10=0.1sを作るためのカウンタです
  }
}

 上のINT_led_flash()関数は、先ほど計算した9.83msごとに割り込みがかかり、呼び出されます。これを10回呼び出されると、0.1秒になります。

 9.8304ms*10=0.09830s=0.1s=約0.1秒
となります。

 led_data=0x01-led_data;//0x01と0x00
を繰り返します。

 0.1sごとにこの式を実行することになり、LEDが0.1sごとに点灯・消灯を繰り返すことができます。

■割り込みの許可

 実際のプログラミングでは、割り込みを許可しないと割り込みは発生しません。

enable_interrupts(INT_RTCC);//割り込み許可
enable_interrupts(GLOBAL);//全ての割り込みを許可

以上を記述すると割り込み動作を開始します。

 なお、割り込みは停止することもできます。

   disable_interrupts(INT_RTCC);

 割り込みが発生するとメイン・プログラムは動作を一時停止して、割り込み処理を優先します。割り込み処理が長くかかるとメイン・プログラムの動作に支障がきたす場合は、割り込みを停止することも必要になります。

 プリスケーラの倍率とタイマ初期値を組み合わせて時間を設定するため、割り込み処理はなかなかやっかいですが、理解すると応用範囲は無限大です。頭の体操と考えて取り組んでください。

 今回は穴埋め★マークはなしですが、次回にのCソース・ファイルとHEXファイルを掲載します。

■ 訂正

割り込み処理の注釈文の中で、

//  9.8304ms*25=0.09830s=0.1sとありますが、

//  9.8304ms*10=0.09830s=0.1sの間違いです。訂正させていただきます。





長野県飯田工業高校 竹内浩一

トラックバック

このエントリーのトラックバックURL:
http://www.eleki-jack.com/mt/mt-tb.cgi/459

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

カレンダ

2008年11月
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30

おすすめ書籍

会社案内
情報セキュリティおよび個人情報の取り扱いについて

コメントとトラックバックは、spamを予防するために、編集担当が公開の作業をするまで非公開になっています。
コメントはそれぞれ投稿した人のものです。

About

2007年10月22日 10:06に投稿されたエントリーのページです。

ひとつ前の投稿は「エレキジャックNo.4の付録基板」です。

次の投稿は「7-8 課題8 割り込み処理 ~その2~」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Powered by
Movable Type 4.1