前回、
~LED点灯編~を実施しました。
p4ddr = 0xffになっていた理由についてはライト専用レジスタで、リードは無効(リードした場合1が読みだされる)という事でした(笑) 。すみません。。。
仕切りなおし、今回は
~タイマー割込み編~になります。
タイマー割込みでLED点滅させるプログラムを作っていきましょう。
では、1secタイマーでLEDをON/OFFできるように作ってみよう。
まず、1secタイマーを作るためには8bit/16bitタイマーどちらを使うか?どのように使うか?
8bitタイマーの場合、タイマーカウンタが8bitの為、255がMAXになる。
8bitタイマーのカウントクロックは分周比8/64/8192の3種類が存在する。
H8-3069Fの動作周波数は20MHzなので、各分周比で割ってやると、
1秒間にカウントアップする回数が算出される。
この1秒間にカウントアップする回数が、TCNTで表現される整数範囲以下でなければ、
カウントできない。分周比8/64は溢れてしまう。分周比8192は割り切れない為、使えない。
なので、16bitタイマーを使用する。
16bitタイマーの分周比は1/2/4/8が存在する。
1秒間にカウントアップする回数は下記の通り。
ここでもTCNTの整数範囲を溢れてしまうので、2段階カウントアップ方式を使って
1secタイマーを実現する。
分周比:8/TCNT0:10000/TCNT1:250
TCNT0が10000になった時にもう一つのタイマーをスタートさせ、
TCNT1が250になった時に割り込みを発生させる事とする。
イメージ的には分周、分周していくイメージになる。
20MHz = 20000000 Hz /8 = 2500000 Hz
2500000 Hz / 10000 / 250 = 1Hz
下記に考え方と、フローチャートを作ってみたので、プログラミングしてみる。
こんな感じ。
main.cmain.c
int main(void)
{
serial_init(SERIAL_DEFAULT_DEVICE);
puts("-----------------Led1 and 2 is Light start!!\n");
/* p4ddr(P46 and P47) output setting 0x0c = 1100 0000 */
/* p4dr (P46 and P47) output 0x0c = 1100 0000 */
P4DDR.BYTE = 0;
P4DDR.BIT.B6 = ENABLE;
P4DDR.BIT.B7 = ENABLE;
P4DR.BYTE = DISABLE;
P4DR.BIT.B6 = LED_ON;
P4DR.BIT.B7 = LED_OFF;
/**
* カウントクロック設定 φ/8
*/
T_16TCR0.BIT.TPSC = 0x03;
T_16TCR1.BIT.TPSC = 0x03;
/**
* カウンタクリア要因の選択
*/
T_16TCR0.BIT.CCLR = 0x01; // GRA
T_16TCR1.BIT.CCLR = 0x01; // GRA
/**
* アウトプットコンペアレジスタの選択
*/
T_TIOR0.BIT.IOA = 0x02; // GRA コンペアマッチ 1出力
T_TIOR1.BIT.IOA = 0x02; // GRA コンペアマッチ 1出力
/**
* IMF フラグ割込 要求許可
*/
T_TISRA.BIT.IMIE = 0x01; //割込 要求許可
T_TISRB.BIT.IMIE = 0x01; //割込 要求許可
/**
* 周期設定
*/
T_GRA0_H.BYTE = 0x2710; // 10000
T_GRA1_H.BYTE = 0x00FA; // 250
/**
* TIMER START
*/
T_TSTR.BYTE = 0x01; // 16TCNT0 Start
while(1)
{
puts("T_16TCNT0:");
putxval(T_16TCNT0_H.BYTE,2);
putxval(T_16TCNT0_L.BYTE,2);
puts("\n");
puts("T_16TCNT1:");
putxval(T_16TCNT1_H.BYTE,2);
putxval(T_16TCNT1_L.BYTE,2);
puts("\n");
puts("T_GRA0:");
putxval(T_GRA0_H.BYTE,2);
putxval(T_GRA0_L.BYTE,2);
puts("\n");
puts("T_GRA1:");
putxval(T_GRA1_H.BYTE,2);
putxval(T_GRA1_L.BYTE,2);
puts("\n");
puts("T_TISRA IMF:");
putxval(T_TISRA.BIT.IMF,2);
puts("\n");
puts("T_TISRB IMF:");
putxval(T_TISRB.BIT.IMF,2);
puts("\n");
if(T_TISRA.BIT.IMF == 0x01)
{
P4DR.BIT.B6 = LED_ON;
P4DR.BIT.B7 = LED_ON;
break;
}else{
P4DR.BIT.B6 =~ P4DR.BIT.B6;
P4DR.BIT.B7 =~ P4DR.BIT.B7;
}
}
return 0;
} |
<実行結果>
-----------------Led1 and 2 is Light start!!
T_16TCNT0:10c7
T_16TCNT1:0000
T_GRA0:10ff
T_GRA1:faff
T_TISRA IMF:01
T_TISRB IMF:00 |
GRA0:0x10FF = dec4351になっている。期待値は0x2710 = dec10000なのに。
とりあえず、本日はここまで。次回デバッグです。
ひとつひとうみていこう。