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なのに。
とりあえず、本日はここまで。次回デバッグです。
ひとつひとうみていこう。
0 件のコメント:
コメントを投稿