割り込みを使ってみよう

割り込み処理とは

 組み込み装置あるいは、ロボットなどは、ADコンバータからなんらかの値を得て、その値によってモーターを動かすことをします。モーターを動かすにはPWM制御という方法を使いますので、タイマーの値を見ながら他の仕事をしなければいけません。
 一般に、一人一人自由に仕事をする使用人全てを一気に監督する現場監督の仕事はかなりきつい仕事で、これを打開するには賢い使用人を用いて、全責任を負わせ、100%の監督をしないことです。一回使用人に仕事を言いつければ、その使用人はその仕事を勝手にやり続けてくれるようにします。プログラミングも同じようなものです。
 プログラミングは、単純なスケジュールではなく、実は何が起こるかわからないスケジュール管理です。実世界と同じです。運動会のプログラムを遂行中に、児童がかけっこ中に転んで膝を擦りむいた、あるいは、竜巻が起こった場合その対策をしないといけません。このようにある程度予想できること、可能な範囲で予測できる事件のことをプログラミング用語では「イベント」と呼びます。このイベントという言葉はソフトウェア寄りの言葉で、ハードウェア寄りの言葉では「割込み」と言っています。ここの説明では、ハードウェアに近いので割込みという言葉を用いていますが、プログラム自体はイベント処理になっています。

 下の図は割り込みの例で、Aの処理をしている間に割込み1が起こり処理ルーチンBを行い、元に戻り、次に割込み2が起こりCの処理を行いここでDの処理の実行予約を行い戻り、Aの処理でDの処理を行うことを示しています。割込み2が起こらなければDの処理は行いません。



 ここでは、LEDを点滅させている間に、タクトスイッチが押されたらそれを報告するだけのプログラムを作ってみます。

配線
Pin22にLEDをつなげます。
Pin23にタクトスイッチをつなげます。スイッチ・オン時にGNDにつながるように配線します。CPU側でプルアップするので抵抗は必要ありません。

タクトスイッチからの割り込み処理プログラム作る



タクトスイッチからの割り込み処理プログラム
using System;
using System.Threading;  
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware; 
using GHI.OSHW.Hardware;        
using GHI.Hardware.FEZCerb;
using BoeBotLib;
using Pin = GHI.Hardware.FEZCerb.Pin;

namespace BoeBotLib
{
    public class Program
    {
        DigitalOut LED1 = new DigitalOut(CPU.P22);
        public static void Main()
        {
            new Program().main();
            Thread.Sleep(Timeout.Infinite);
        }

        InterruptPort _ButtonDown;

        InterruptPort mkPort(Cpu.Pin pin)
        {
            return new InterruptPort(pin, true,
             Port.ResistorMode.PullUp,
            Port.InterruptMode.InterruptEdgeLow);
        }
        void ButtonDownOnInterrupt(uint portPin, uint level, DateTime time)
        {
            Debug.Print("Button On " + portPin + " "+ level + " " + time);
        }

        private void main()
        {
            _ButtonDown = mkPort(CPU.P23);
            _ButtonDown.OnInterrupt += ButtonDownOnInterrupt;

            while (true)
            {
                LED1 <<= 1;         // LED1.Write(true);
                CPU.delay(500);
                LED1 <<= 0;         // LED1.Write(true);
                CPU.delay(500);
            }
        }
    }
}
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 InterruptPortオブジェクトを作るメソッド
24 チャタリングの処理をする
25 割り込む入力ポートはプルアップする
26 立下りエッジで割り込む
27 
28 
29 割り込み処理ルーチン
30 portPin : 割り込んできたピン番号
31 level   : 割り込んできたレベル
32 time    : 割り込んできた時刻
33 
34 
35 
36 InterruptPortオブジェクトをP23に対して作る
37 割り込み処理ルーチンをButtonDownOnInterruptに設定
38 
39 LEDの点滅を永久に行う
40 
41 
42 
43 
44 
45 
46 
47 
48