前回二桁で押された回数をカウントするプログラムを作りましたが、今回はTimerAを用いて1秒ごとに自動でカウントアップするようにします。
TimerCountUP.c
//1秒ごとにカウントアップするプログラム
#include <stdio.h>
#define BRR (*((unsigned char *)0xFFA9))
#define TMA (*((unsigned char *)0xFFA6))
#define IRR1 (*((unsigned char *)0xFFF6))
#define IRRTA 0x40
//TimerAはIRR1の第6ビットが立つ
#define PMR1 (*((unsigned char *)0xFFE0))
#define PMR5 (*((unsigned char *)0xFFE1))
#define PCR1 (*((unsigned char *)0xFFE4))
#define PCR5 (*((unsigned char *)0xFFE8))
#define PCR7 (*((unsigned char *)0xFFEA))
#define PCR8 (*((unsigned char *)0xFFEB))
#define PDR5 (*((unsigned char *)0xFFD8))
#define PDR7 (*((unsigned char *)0xFFDA))
void wait();
main()
{
unsigned char LED[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7d,0x27,0x7f,0x67};//1の位用配列
unsigned char LED10[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfc,0xa7,0xff,0xe7};//10の位用配列
int i,count=0,count10=0;
//SWの状態記憶用
int OldState=0;
int State=0;
BRR=12; //16MHZ時には12を デフォルトは7 ボーレート変更
PMR1 = 0x00; /*ポート1を汎用IOに設定*/
PMR5 = 0x00; /*ポート1を汎用IOに設定*/
TMA = 0x18; //1秒
PCR1 = 0xff; //アドレス FFE4
PCR5 = 0xff; //FFE8
PCR7 = 0x00;
PCR8 = 0xff; //FFED //00入力 ff出力
for (;;) {/* 無限ループ */
PDR5=LED[count];
wait(500);
PDR5=0x00;
wait(50);
PDR5=LED10[count10];
wait(500);
PDR5=0x00;
wait(50);
State=0;
if((IRR1 & IRRTA) != 0){
State=1;
IRR1 &= ~IRRTA;//IRRTAを~IRRTAと反転させIRR1と&をとりフラグを解除する
}
if(OldState!=State && OldState!=1){
if(count<9){
count++;
}
else{
count10++;
count=0;
}if(count10>=9)count10=0;
}
OldState=State;
}
return 0;
}
void wait(int n)
{
int i;
for(i=0;i>n;i++);
}
今まで飾りと化していたTMAにようやく出番が回ってきました。
#define TMA (*((unsigned char *)0xFFA6))
#define IRR1 (*((unsigned char *)0xFFF6))
#define IRRTA 0x40
TMA
タイマAの機能は、「タイマモードレジスタA(TMA)」より設定します。
TMA = 0x18; //1秒 0001 1000
TMAの第3ビットを1にすると時計用サブクロック、0にするとシステムクロックを使うことができます。今回は1をたて時計用クロックを使います。
1秒間隔の周期イベントを発生させるには、TMAの第2ビットから第0ビットを「000」とすることで周期を1秒に設定することができます。第7ビットから第5ビットはクロック出力のためのものなので今回は使っていません。
000 1秒
001 0.5秒
010 0.25秒
011 0.03125秒
IRR1
タイマAの発生する周期イベントは、IRRによって通知されます。IRRTAフラグは「割り込みフラグレジスタ1(IRR1)」の第6ビットにあります。IRRTAフラグは、タイマカウンタがオーバフローすると「1」にセットされますが、IRRTAフラグは1がたったらその後変化しなくなるので、プログラム側で0に戻してやる必要があります。
そのため今回は
#define IRRTA 0x40
を定義し
IRR1 &= ~IRRTA;
で0に戻しています。