As we mentioned before the RTC will not work for you with the BAP40 as it does not have a 32khz crystal. But as I mentioned earlier either here or on the Lynxmotion thread, you can use the standard timers on the processor to time things... We do this all the time with several of our robots, like the Lynxmotion Phoenix...
The question is which timer to use. That often depends on other things like, what other things are you using in your program, duration of what you are trying to time and how high a resolution you need, it is all a set of trade offs.
The best timer to use for many things is TimerZ (TimerW on Bap24/28) as this is the only 16 bit timer. Which at it's lowest resolution (clock/8) will overflow about 38 times per second. But, TimerZ is used for HSERVO and/or HPWM or... So if you use any of these hardware features you probably can not use this timer. But if you are not using these other features and what you are timing is of a short enough duration that the clock does not overflow, than you can simply use this timer with no overhead. Simply initialize the timer and either grab or reset the TCNT (0 or 1 depending on how set up) at the start of what you are timing and then grab TCNT at the end and if you reset this is your DT or simply subtract off the value you grabbed at the start...
But if TimerZ does not work for you than there is the two 8 bit timers. TimerB0 and TimerV. Each with their own pluses and minuses. Unless you are timing something with a really short duration, you will probably need to setup an interrupt handler, which is not hard, but there are issues. That is if an interrupt occurs while you are doing some bitbang type operations, like SERIN/SEROUT... It is very possible the interrupt code will corrupt the data you see from those bitbang functions. But in many cases you can work to avoid this. On Bap40 you can use HSERIAL to talk to the debug terminal and another device as well, which avoids bit bang. Also you can work to turn off interrupts while the bit bang is happening. I do this with phoenix code, knowing that I will reenable them quick enough not to lose any... I will try to show some extracts of the code that shows an example of using TimerB1...
Code:
;[TIMING]
lTimerCnt var LONG ; used now also in timing of how long since we received a message
lCurrentTime var long
lTimerStart var long ;Start time of the calculation cycles
lTimerEnd var long ;End time of the calculation cycles
CycleTime var word ;Total Cycle time
...
TIMERINT con TIMERB1INT
ONASMINTERRUPT TIMERB1INT, HANDLE_TIMERB1_ASM
...
WTIMERTICSPERMSMUL con 256 ; Arc32 is 20mhz need a multiplyer and divider to make the conversion with /8192
WTIMERTICSPERMSDIV con 625 ;
TMB1 = 0 ; clock / 8192 ; Low resolution clock - used for timeouts...
...
ENABLE TIMERINT
ENABLE
...
'Start time
GOSUB GetCurrentTime[], lTimerStart
...
do whatever it is you want timed...
...
;Get endtime and calculate wait time
GOSUB GetCurrentTime[], lTimerEnd
CycleTime = ((lTimerEnd-lTimerStart) * WTIMERTICSPERMSMUL) / WTIMERTICSPERMSDIV
...
BEGINASMSUB
HANDLE_TIMERB1_ASM
ASM {
push.l er1 ; first save away ER1 as we will mess with it.
bclr #5,@IRR2:8 ; clear the corresponding bit in the interrupt pending mask
mov.l @LTIMERCNT:16,er1 ; Add 256 to our counter
add.l #256,er1
mov.l er1, @LTIMERCNT:16
pop.l er1
rte
}
ENDASMSUB
;==============================================================================
;[GetCurrentTime] - Gets the Timer value from our overflow counter as well as the TCB1 counter. It
; makes sure of consistency. That is it is very possible that
; after we grabbed the timers value it overflows, before we grab the other part
; so we check to make sure it is correct and if necessary regrab things.
;==============================================================================
GetCurrentTime:
lCurrentTime = lTimerCnt + TCB1
; handle wrap
if lTimerCnt <> (lCurrentTime & 0xffffff00) then
lCurrentTime = lTimerCnt + TCB1
endif
return lCurrentTime
Note: I simply extracted code fragments from an older version of phoenix code as the current code had Bap40 support removed... So I did not try to compile or the like, but this should give you an idea.
For areas that you do bit bang output, you may need/want to add so disable/enable timer around the call. Something like:
Code:
disable Timerint
serout ...
enable TimerInt
This is fine for short durations as the TimerB1 with a clock divide of 8192 will only overflow about 9.5 times per second so as long as your disable is less than 1/9.5 seconds you should not lose an interrupt.
But if resolution of clock/8192 is not sufficient for you, than you need to update the init code plus time conversion constants, which will cause more interrupts per second...
Hope that helps
Kurt