Hi again dan,
Sorry, I don’t think there are any complete tutorials on using timers.
Did you look at all at the thread I passed a link to or the sections on the different timers on the H8 processor? There are other threads such as:
lynxmotion.net/viewtopic.php?t=2653&highlight=timer, which talk about it some.
But put in the simplist terms, the timers can be used as machine clock counters. That is, the processor will automatically increment a system register on every N clock cycle regardless of what else is going on. You can select the clock scalling by setting a system register. For the remainder of this post I will only talk about TimerA. Note: some of these timers have some other interesting capabilities that I will not discuss here.
To use TimerA, you will need to setup your scaling. This is done by setting certain bits in the TMA register. For our example, the valid values for TMA are:
0: Æ/8192
1: Æ/4096
2: Æ/2048
3: Æ/512
4: Æ/256
5: Æ/128
6: Æ/32
7: Æ/8
As the clock on the BAP28 runs at 16,000,000 cycles per second (more or less), if you choose lets say TMA=6, then the clock will increment every 32 cycles or about 2uS. The running system counter for TimerA is kept in the system register TCA. As TimerA is an 8 bit counter, TCA is only 8 bits in length and will overflow when it wants to hit the value of 256. For now I will assume you wish to time things that take more than 256 units (actually 512 as you could use the overflow indicator…, but…). To do this you will probably want to enable the interrupt on the TimerA overflow and provide an interrupt handler, which increments a counter of how many interrupts that have happened. An example of this is in the forum post that I put a link to in the previous message.
Here is some more sample code from one of my programs. Currently I only use this when debugging so I only made the counter to be 16 bits, but I could just as easily made it 32 bits.
wTimerCnt var word ;
wTimerCnt = 0
...
; Initialize the timer stuff
TMA = 6 ; clock / 16
ONASMINTERRUPT TIMERAINT, HANDLE_TIMERA_ASM ; set interrupt handler
ENABLE TIMERAINT ; enable the timer interrupt
ENABLE ; globabl enable interrupts
...
;--------------------------------------------------------------------
;[Handle_Timer_asm] - Handle timer A overlfow in assembly language. Currently only
;used for timings for debuging the speed of the code, may be pulled later or may be
;used for timing delays.
BEGINASMSUB
HANDLE_TIMERA_ASM
push.w r1 ; first save away ER1 as we will mess with it.
bclr #6,@IRR1:8 ; clear the cooresponding bit in the interrupt pending mask
mov.w @WTIMERCNT:16,r1 ; Add 256 to our counter
inc.b r1h
mov.w r1, @WTIMERCNT:16
pop.w r1
rte
ENDASMSUB
;--------------------------------------------------------------------
;[getTimerVal] - Gets the Timer value from our overflow counter as well as the TCA counter. It
; makes sure of consistancy. That is it is very posible that
; after we grabed the timers value it overflows, before we grab the other part
; so we check to make sure it is correct and if necesary regrab things.
bTimerTmp var byte
GetTimerVal:
bTimerTmp = WtimerCnt.highbyte
wTimerCnt.lowbyte = TCA
if wTimerCnt.highbyte <> bTimerTmp then GetTimerVal ; make sure consistent value
return
In this example I did use an assembly language interrupt handler for speed, but could have made it a basic hander, which would have been something like:
ONINTERRUPT TIMERAINT, HANDLE_TIMERA
...
HANDLE_TIMERA:
wTimerCnt = wTimerCnt + 256
resume
Again Could have easily extended to 32 bits.
I also had a helper function to try to get a consitent value. That is there are chances that when you are grabing the current timer value, that at that instant the timer wrapped around and an interrupt happened and your value will not be correct…
I hope this helps.
Kurt