タイマーを使う(タイマーA)
タイマーで正確な時間稼ぎをする
考え方など基本は同じですので、まず Tekurobo工作室
103.タイマーで正確な時間稼ぎをする を見てください
LEDを空ループで間隔をとり点灯させてきましたが、今度はタイマー機能を使用して、正確な間隔時間を作ります。
H8-3048F CPUには、ITU タイマーが5つもあるそうです・・・
H8-33664には、でも3つのタイマーがあります。タイマーW、タイマーV、タイマーA
タイマーの数が少ないでので、3664は何軸もモーターを制御するような目的では使いずらいですね。しかし工夫のしがいもあります。。。
3048には無いタイマーとして 3664にはタイマーAがあります!(たいした機能ではないのですが・・)
しかし、3048とかにはないのでちょっと貴重。このために水晶発振器がついているし、、数少ない優位点かも。
タイマーW、Vは またモーター制御などで使うことになるので、LED間隔に今回はこれを使用します。
タイマーA
タイマーAは設定時間が来る毎にベルがなるような簡単に利用できるタイマーです。時計のような時間も割と簡単につくれます。
発振も水晶発振器なのでより正確ですしね 多分、このタイマーは時計機能を目指して付いているのでしょう。
ここではそのタイマーAを使ってみます。
特徴
- 2種類-低速、高速発振を選択可能
メインクロック 、 32.7kHz低速時計用クロック - そのクロックを端子から出力設定も可能
- タイマ割り込み可能
動作
- タイマー動作をスタートさせると、8bitのTCA(タイマカウンタ)がカウントを開始します (TCAはリードのみ)
- タイマーAは コンペアマッチでなく、オーバーフローだけで設定時間を得ます。
つまり、設定時間がくるごとにお知らせしてくれる - TCAがオーバーフローすると 割り込みフラグレジスタ1(IRR1)IRRTAが1にセットされる
- TCAは TMAのTMA3とTMA2を 1 1 にすることでリセットできる。
設定
レジシタなどの説明
タイマーAの初期設定は タイマーモードレジスタA (TMA) で設定します。
(レジスタ1つ、1バイトで設定がすんでしまいます お手軽です)
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ビット名 | TMA7 | TMA6 | TMA5 | - | TMA3 | TMA2 | TMA1 | TMA0 |
(端子発振クロック速度入力) 端子から出力しないとき必要ない |
- | 発振器選択 | クロック速度入力 |
TMA3で 低速、高速どちらかのクロック種類を使用するか選択します。
TMA3 : 0 or 1 でそれぞれ下記のようにクロック速度を入力し選択します
TMA3 : 1 のとき 低速時計用クロック |
|||
TMA2 | TMA1 | TMA0 | 時間 |
0 | 0 | 0 | 1s |
0 | 0 | 1 | 0.5s |
0 | 1 | 0 | 0.25s |
0 | 1 | 1 | 0.3125s |
1 | 0 or 1 | 0 or 1 | リセット |
TMA3 : 0 のとき 高速クロック |
|||
TMA2 | TMA1 | TMA0 | 時間 |
0 | 0 | 0 | φ/8192 |
0 | 0 | 1 | φ/4096 |
0 | 1 | 0 | φ/1045 |
0 | 1 | 1 | φ/512 |
1 | 0 | 0 | φ/256 |
1 | 0 | 1 | φ/128 |
1 | 1 | 0 | φ/32 |
1 | 1 | 1 | φ/8 |
TMA7、TMA6、TMA5 は端子からクロックを出力したい場合のみに入力が必要です
そのクロック速度を入力します。
クロックを端子出力しない場合は必要ありません
端子クロック出力をする設定は PMR1レジスタで設定 TMOW端子から入力したクロックが出力される。
端子からクロック出力する設定
- PMR1レジスタ Bit0: 0 にし、TMOW に出力設定にする。
- TMA7、TMA6、TMA5 で端子から出力したいクロックを入力
- TMOW端子(1CH P20)からクロックが出力される
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名称 | - | - | - | - | - | - | - | TMOW |
- | - | - | - | - | - | - | 1: 入出力ポート 0: TMOW出力端子 |
TMOW端子(1CH P20)から出力クロック
TMA7 | TMA6 | TMA5 | 出力クロック時間 | φ : 高速クロック発振器 W : 低速時計用クロック発振器 |
0 | 0 | 0 | φ/32 | |
0 | 0 | 1 | φ/16 | |
0 | 1 | 0 | φ/8 | |
0 | 1 | 1 | φ/4 | |
1 | 0 | 0 | W/32 | |
1 | 0 | 1 | W/16 | |
1 | 1 | 0 | W/8 | |
1 | 1 | 1 | W/4 |
実際のレジスタ設定
TMAレジスタの設定値は 時計用クロック 時間0.5sとするので下記になります。
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ビット名 | 0 | 0 | 0 | - | 1 | 0 | 0 | 1 |
- | 時計用クロッ ク器を使用 |
0.5s |
上記TMAレジスタで初期設定をすると、その他の設定、利用などは
IRR1.BIT.IRRTA=0; 検知フラグ
IENR1.BIT.IENTA=1; 割り込み許可
int_timera() 割り込み関数
タイマーAは オバーフローだけで設定設定時間経過を得ます(コンペアマッチはなし)
設定時間が来ると(オーバーフローすると)
IRR1.BIT.IRRTA =0 が 1になり、設定時間が来たことがわかります。
割り込みを使用するときは
IENR1.BIT.IENTA=1; 割り込み許可
として
int_timera() 割り込み関数 を使用します。
割り込み関数は GDLでは各割り込み関数名が決めらているので、タイマA割り込み関数にはこれを使用し、変更はできません。
実験回路図
回路は IOポートでLEDを光らせる と同じ回路を使います。
プログラム
タイマAを使ったLED点灯
LED点灯で msecwait() 関数 で待ち時間を空ループにしていたのを、タイマAを使用して正確な待ち時間を作ってみます。
その後、同様の動作を タイマAの割り込み関数を用いて動作させるプログラムもやってみます。
TAwait() で間隔時間をつくります。これによりタイマAによって正確な時間で間隔をとる。
呼び出される間隔は設定時間(0.5s)です、
for ループ内で 設定時間のお知らせが2度来るるまで ループを抜けないので 0.5×2回で 1秒間隔になっています。
TmrLed1
#include "3664.h"
/* タイマーA の時計タイムベース動作 */
/* オーバーフローすると IRR1.BIT.IRRTA = 1 になる
タイマAは スタート、ストップの機能なし 設定するとスタートする
*/
void TAwait(int ms){
int i;
for(i=0;i<=ms;i++){
// TCA(TCNT) =オーバーフロー(GRA)になるまで待つ
while(IRR1.BIT.IRRTA == 0);
IRR1.BIT.IRRTA = 0; // 検知フラグを戻して再開
}
}
void main()
{
IO.PMR1.BYTE=0x00; /* 全て0にセットし、全ピンをポート使用に設定 0000 0000*/
IO.PCR1=0xFF; /* 全て1にセットし、出力に設定 1111 1111 */
/* PCRレジスタは IO.PCR1.BYTE 記述でない!*/
IO.PUCR1.BYTE=0x00; /* 全て0にセットし、プルアップなし*/
TA.TMA.BYTE=0x09; /* 時計用クロック 時間0.5s 0000 1001 */
while (1) {
IO.PDR1.BIT.B4=1; /* P14--pin20 */
IO.PDR1.BIT.B5=0; /* P15--pin21 */
TAwait(2);
IO.PDR1.BIT.B5=1;
IO.PDR1.BIT.B4=0;
TAwait(2);
}
}
実行結果
1秒ごとにLEDが1つずつピコピコと点灯します。
- twtter
- google+
- hatena