## Convert Timer1 value to meaningful number

9 posts / 0 new
Author
Message

Hi,

Processor: mega169 (Butterfly)
Clock: 8MHz (external oscillator)
Timer1 prescaler: clkio/1024
Language: Assembly

I have an application where I want to measure the time it takes to stop a motor shaft once a brake is applied. The Butterfly has two inputs: one that tells it when the brake is applied and the other tells it if the shaft is spinning. It seems pretty simple, you just start Timer1 when the brake is applied and read Timer1 when the shaft stops spinning. The problem, for me, is how to convert the Timer1 value into something meaningful that can be displayed on the Butterfly display.

Each count in Timer1 represents 128 microseconds (8MHz divided by 1024 = 7812.5Hz = 128 microseconds). It seems logical to me that you would then multiply the Timer1 value by 128 to get the total number of microseconds...is this a correct assumption?

If I want the display to be in milliseconds then I just divide the microseconds value by 1000...correct?

I am sorry, I just seem to be having trouble convincing myself that it would be that simple. I have working multiply and divide routines (thanks to Atmel app notes :-) ) so that part is not the problem. I am just having a brain fart I guess.

Thanks,
Steve

Total votes: 0

Yes and yes - you are very very close to getting it working just fine.

Cliff

Total votes: 0

Steve,

Sometimes we look for the hard way when, it's really just that simple.

I went through you math and it seems correct.

The timer counter value times 128 would give multiples of 128uS. That divided by 1000 would provide miliseconds with 128uS resolution.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

Total votes: 0

Thanks !!

Total votes: 0

Remember that * 128 / 1000 is the same as * 32 / 250.

If you are selecting an external clock source, wouldn't it be even more simple to use 8.192MHz? Or some other value that gives the resolution that you need with a convenient prescaler value.

Remember to have a Timer1 Overflow ISR to handle stop times longer than 6 seconds, and/or abort if the stop signal is never received.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Total votes: 0

theusch wrote:
Remember that * 128 / 1000 is the same as * 32 / 250

Which is the same as 16/125 and I can't help noticing that 125 is fairly close to 128 so if you didn't mind a little over 2% error you could simply divide by 8 (that is * 16 / 128), or IOW, shift right 3 bits.

Cliff

Total votes: 0

I like the way you think Cliff.

If answer is a single-byte:

```C2MSEC: LDI B,33
MUL A,B   ;R1=A*128/1000
```
Total votes: 0

Hi,

You all's (yawl's :-) ) comments spurred me to think about my approach differently. I am locked into using 8.00MHz because I am writing code for existing hardware. The code is only going to be used for a couple of weeks and then the hardware will be reprogrammed with the original code and put back to its original use. However, I realized that if I use a prescaler of /8 then I will have a 1 microsecond clock going into Timer1. If I am understanding things correctly I can use WGM Mode 4 (CTC using OCR1A) to count 1000 "1 microsecond" periods. I can then count the 1 millisecond periods.

(A question: Am I reading the datasheet correctly that the Output Compare 1A flag will be set on the next Timer1 clock after the match? That means I need to setup OCR1A to 999 instead of 1000, correct? Sorry, first time using anything other than very basic Timer functionality. I have to add, I understand why so many people get frustrated trying to setup PWM and so forth using these timers. You really do have to read EVERYTHING and read it several times...at least I do :-) .)

So, my thinking is that it will be easier and more efficient to count the 1 millisecond periods in BCD. (I threw together a routine that takes only around 16 cycles to count 4 digits in BCD, giving me up to 9.999 seconds, only need 2 seconds or so though.) This would be instead of the multiplies and/or divides and BIN2BCD conversion that my other idea would have required. (I am using existing code for displaying data on the Butterfly display that requires BCD data...and I don't want to redo that code :-) .)

So thanks for making me think about this more.

Regards,
Steve

Total votes: 0

Quote:

That means I need to setup OCR1A to 999 instead of 1000, correct?

In general, yes. The way I try to keep it straight in my head is if you set the compare match to 1, then there are "ticks" for both 0 and 1, so there are two ticks. Extrapolate to bigger numbers. ;)

It gets weird also in up-down counting modes.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.