2016-05-01 19:32 — asano
まずは前回の宿題の回答を載せておきましょう。
- PB0~7を全て"L"にします。
- PD0を"L"、PD1~3を"H"にします。
- PD4を読んで"L"ならSW1が押されていると判定。
- PD1を"L"、PD0,2,3を"H"にします。
- PD4を読んで"L"ならSW2が押されていると判定。
- 同様にSW3,4も判定します。
もし4つで不足ならPD5も使えば8つまで増やせます。
PB0~7を"L"にしておくのはキーのスキャン中にQ1~4がOnしてしまうからです。LEDは一瞬でも点灯すると意外に目立つことがあるので注意したほうが良いです。逆にLEDのスキャン中にはPD4に変な入力がありますがソフトで無視するので問題ありません。
それではソフトウェア編に行きましょう。比較的新しかった(タイムスタンプによると15年ほど前)のでソースコード等はすぐに見つかりました。一式をtimer.tgzとして置いておきます。使っているアセンブラはAVRAの古いバージョン(0.4)のようです。
ソースコードを逐一解説しませんが、いくつか特徴的なところを思い出して書いてみます。
- 割り込み処理が長い
「割り込みハンドラで複雑なことをするな」とはよく言われることですが、実は大半の処理を割り込みハンドラで実行していてメインルーチンより割り込みハンドラの方が長いです。それも一つの1/1024秒のタイマ割り込みで- 1024Hzの分周と秒・分のカウント処理
- キーのチェックと長押し時のリピート処理
- LEDのスキャン処理
- ブザーの音程生成の処理
を行なっています。
もうちょっと頑張ればメインルーチンを単なる初期化と無限ループに出来たかもしれません。 - 割り込みでレジスタ退避をしない
そもそもこのAT90S1200にはRAMが無いので(割り込みの戻り番地は専用の数段のスタックがあります)退避のしようが無いのです。それでも32本もあるレジスタをメイン用と割り込み用に分ければ問題はありません。r2 割り込みハンドラからメインへの押されたキーの通知 0x00 No key 0x11 Key 1 (Press) 0x12 Key 2 (Press) 0x23 Key 3 (Release) 0x31 Key 1 (Repeat) 0x32 Key 2 (Repeat) r3 リピート開始のカウンタ r4 直前に押されていたキー r5 1/1024秒のカウント r6 1/256秒のカウント r7 Timer mode 0 停止状態 (STOP) 1 カウント状態 2 鳴動状態 r8 カウント中の「分」の十の位 r9 カウント中の「分」の一の位 r10 カウント中の「秒」の十の位 r11 カウント中の「秒」の一の位 r12 1桁目表示内容 (「分」の十の位) r13 2桁目表示内容 (「分」の一の位) r14 3桁目表示内容 (「秒」の十の位) r15 4桁目表示内容 (「秒」の一の位) r16 メインルーチンでの作業用 r23 メインルーチンでの作業用(r7判定用) r24 設定中の「分」の十の位 r25 設定中の「分」の一の位 r29 割り込みハンドラでの作業用 r30 割り込みハンドラでの作業用 r31 割り込みハンドラでの作業用 - ブザーの断続と音程
512Hzの音程と1/8秒の断続はとても短い処理でまとめて作っていますが、わかりますか?
添付ファイル:
関連項目:
コメントを追加