List 3からの変更点は、alt_alarm関数への対応、それとキー入力への対応である。
まずKEY_START/KEY_HOLD/KEY_STOP/KEY_RESETという4つの定義が出てくるが、これはKEY 0〜KEY3の4つのキーそれぞれへの対応である。今回の場合、IORD_ALTERA_AVALON_PIO_DATA(KEY_BASE) を呼ぶとキーの状態が5bitの形で返ってくるが、0bit目がKEY 0、1bit目がKEY 1...となっており、それぞれに対応した形だ。
新しくAlarm_Int()という関数が追加されているが、これはAlarmで呼び出されるCallback関数だ。今回の場合、Alarmは1msにセットされている(つまりAlarm_Int()は1ms毎に呼び出される)事になるので、内部でカウンタを回して100回(つまり100ms)経過したらNum(0.1秒単位のカウンタ)を1つ増やし、それにあわせてLEDと7セグメントLEDの表示を行って戻るだけの処理を行う。
一方メインルーティンだが、while(1)の中でまずキーの値を読み取り、何かしらキーが押下されていた(7セグメントLEDと同じく、押されていないと1、押されると0がbitfieldに返ってくる)ら、それにあわせてAlarmをストップしたりスタートしたり、あるいはカウンタ(TickとNum)をクリアしたり、といった処理を行っているだけである。
余談になるが、先にPhoto03のキャプションでこのKEYの入力についてはEdge Captureを最終的に無効にしたと書いた。本来この機能は、割り込みと組み合わせて使うものだ。Photo03を見ると「Interrupt」という項目があって、必要ならキーの押下を検出して割り込みを発生させることができる。この際、押しっぱなしにすると延々割り込みが発生するのはまずいので、押された瞬間を検出しようというわけだ。
ところが今回の様にポーリングで検出する場合、押された瞬間があまりに一瞬すぎるためにほぼ取りこぼす。そんな訳で今回は「押されている」という状態を検出するようにしたわけだ。
さらに余談になるが、こうした確認にはprintfデバッグが有効である。ところがメモリが64KBだとprintfが動かない(厳密にいえば、printf ("Hello, world\n");は動作するが、printf( "Hello, %d", 100);はメモリが足りずにビルドに失敗する)ため、128KBにしたというわけだ。
さて、あとはビルドして実行させるだけである。実行結果はこんな感じ(Movie02)である。ボタンは右からSTART/HOLD/STOP/RESETに設定されており、7セグメントLEDで秒を、10個のLEDで0.1秒をそれぞれ示している。
Copyright © ITmedia, Inc. All Rights Reserved.