演習3:複数のLEDを光らせる

これまで delay() でタイミングを調整しながらGPIOを制御してLEDを点滅させていました。今回はタイマー割り込みという機能を使って点滅させます。

サンプル(1):複数のLEDを同時に点灯する

Lチカの演習を元に、5×5の左上のLEDと、その右隣のLEDを2個同時に光らせてみてください。下のプログラムはそれぞれのLEDに対応するGPIOを単純に設定しているだけです。動作に変化が無いので loop() の中は何もありません。

結果は意図しないLEDまで計4個のLEDが光ってしまったはずです。

課題1

2個のLEDを光らせようとしたのに、4個光ってしまった理由を説明してください。

サンプル(2):2個のLEDを交互に点滅する

下のプログラムを micro:bit に書き込んで何が起きるか見てみましょう。

左上のLEDが0.5秒毎にオン・オフしたと思います。このプログラムで何が起きたのか説明します。

1行目の #include “nrf.h” は micro:bit に搭載されている ARM Cortex-M0 nRF51822 の機能を利用するためのライブラリをインクルードしています。setup() の中の「//タイマ設定」のコメント以降に10行ほどにわたってタイマー割り込みという機能についての設定情報が書いてあります。その内容は nRF51822 のスペックシート を照合すればわかるのですが、詳細に過ぎるのでここでは省略します。この設定によって0.5秒毎にタイマー割り込みが発生します。0.5秒という時間を設定しているのはこの部分です。

以上の設定によって TIMER2_IRQHandler() という関数が0.5秒の割り込みの都度コールされます。このような、割り込み処理でコールされる関数は、割り込みハンドラーと呼ばれることが多いです。この関数の中で左上のLEDを オン→オフ→オン… と切り替えています。オン/オフの区別は status という変数を使って制御しています。

メインループの loop() には何も書いてないことに注目してください。割り込み機能を使うと、メインの処理とは独立して別の動作させることができます。

課題2

サンプル(2)を元に、5×5の左上のLEDと、その右隣のLEDを交互に点滅させるプログラムを作成してください。

サンプル(3):2個のLEDを交互に “高速に” 点滅する

課題(2)のネタバレになりますが、サンプル(2)のプログラムの前半を次のように書き換えれば左上のLEDと、その右隣のLEDを交互に点滅します。

課題3

サンプル(2)で、割り込みが発生する0.5秒の時間を設定しているプログラム部分を説明しました。そこを次のように変更して、どのような動作になるか観察し、なぜそのなるのか説明してください。

課題4

タイマー割り込みを使って、任意のLEDを同時にオン/オフする機能を作ってください。オン/オフさせる場所の指定は LED[5][5] という配列を使うものとします。

ヒント:時間を3分割してROW1/ROW2/ROW3に接続されたLEDだけをCOL1〜COL9で制御すれば実現できます。

回答例はこちら

課題5

課題4のプログラムについて解説してください。

  • 変数 LED[5][5] の役割
  • 変数 row の役割
  • 変数 ROWLIST[3][9][2] の役割

 

コメント