Olimex ATMEGA-128-MT board and timers...

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi - I'm using the above development board to play with timers a bit (I'm a-lernin) - the Deveopment environment is AVR STudio 4.13 SP1 build 557 & latest released WinAVR (about 1 week old - not the development one).

I've initialised timer 0 as follows:

	TIMSK = _BV(OCIE0);

	ASSR  = _BV(AS0);			// Use 32KHz xtal on TOSC1

	OCR0  = 32;					// One second timer

	TCCR0 = 0<<FOC0   |
			1<<WGM01  |			//  = 10 (CTC mode)
			0<<WGM00  |

			0<<COM01  |			// COM<01:00> = 00 (Disconnect OC0)
			0<<COM00  |
			1<<CS02   |			//  = 111 (/1024)
			1<<CS01   |
			1<<CS00;

	TCNT0 = 0;

	// Wait for updates to complete
	while ( ASSR & (_BV(OCR0UB) | _BV(TCR0UB) | _BV(TCN0UB)) )
	{
		;
	}

Now this should be a one second timer, as there is a 32KHz watch crystal between TOSC1 & TOSC2.

The ISR is defined as follows:

//
// Timer 0 ISR
//
// Like all ISRs, keep it simple, keep it small, keep it fast..
//
ISR(TIMER0_COMP_vect)
{
	if ( PORTD & _BV(7) )
	{
		PORTD &= ~_BV(7);
	} else {
		PORTD |= _BV(7);
	}
}

and port D is set up:

	// Port D initialization
	PORTD	=0x00;
	DDRD	=0b10001000;

So, I think PORTD.7 should oscillate at a steady 2 Hz, but it runs slightly erratically and overall, slow.

Using an HP 5385A ovened frequency counter with a 10 second gate time, I see the frequency about 1.8% low.

However, and here's the bit that confuses me, when I set OCR0 to one and reduce the prescaler count, the timing is spot on at whatever fraction of 32KHz it should be - upping OCR0 seems to throw the whole thing out.

Am I missing something here? I haven't 'scoped the power etc lines yet for noise, but I'm am confused as to why changing OCR0 produces such erratic results - the prescaler seems fine.

FWIW, the main loop is:

int main(void)
{
	// Disable watchdog
	wdt_reset();
	wdt_disable();

	init_ports();

	init_timer0();

	sei();

	while (true)
	{
		if ( !(PINA & _BV(0)) )
		{
			reset = true;
		}
	}
}

Any ideas much appreciated. I'm obviously missing something obvious...

Nicko

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Small update - when I change the code to toggle OC0, I get a steady 0.9999... Hz which is pretty good.

So why the randomness in the ISR? Not trivia, either, its nearly 2% out...

Nicko

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I get a steady

Quote:

So why the randomness in the ISR?

??? So is it steady, or jittery?

Quote:

// Like all ISRs, keep it simple, keep it small, keep it fast..

Have you looked at what your compiler is actually producing for this?

Why are you disconnecting OC0 if you want to truly gauge timer precision? CTC with toggle mode will consume >>no<< CPU cycles. You will arways get a bit of jitter even with an ideal ISR. For example in your main loop you have conditional & jump instructions which are more than one cycle. The current instruction needs to finish before the ISR is invoked. But that would be only a cycle or two and should cancel out the next time.

Now, I'd need to decipher your timer setup with the datasheet. A short answer is that with compare match and auto-reset of the count that you need to set your OC value one less than the number of counts, since both 0 and TOP are counted.

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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is some fine print on page 40 of the mega128 poopsheet that says something about dont use timer0 and the xdiv at the same time. That doesnt apply to your situation does it? Maybe you need to use OCR0 of 31 instead of 32? How about let the timer freerun and arm the overflow int, and count 128 overflows to get the 1 sec? I have an mt128, but I havent used the 32k osc yet....

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the comments.

theusch wrote:
??? So is it steady, or jittery?

Depends where you measure it - on the OC0 pin, its steady but slow...
Quote:
Why are you disconnecting OC0 if you want to truly gauge timer precision?

I'm not - in the second post I changed the code to enable the use of OC0, that's how I could measure it...

Anyway, it seems that the count should be 31, not 32. This is annoying as various Atmel APP notes say that 32 is correct, e.g. AVR130 on page 12 demonstrates using a timer to generate a 1 second interrupt. On the device they chose, its timer 2 that can asynchonously use the TOSC1/TOSC2 watch crystal, but they use 32, and not 31 in the OSC with a prescale of 1024. Is the app note wrong?

Also, mea culpa, the HP frequency meter I was using is AC coupled, and has a low-limit of 10Hz, so it was not helping... now that I'm using a DC coupled counter, its more steady...

Nicko

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Anyway, it seems that the count should be 31, not 32. This is annoying as various Atmel APP notes say that 32 is correct, e.g. AVR130 on page 12 demonstrates using a timer to generate a 1 second interrupt.

It depends what mode you are using for the timers, and what gets "counted" each cycle. If one was counting up and overflowing, then the 8-bit timer would have 256 steps, 0-255.

If one uses a mode such as CTC that matches and resets, then it counts to the match number. So if the match number is 255, it counts 0-255, still 256 steps.

One size does not fit all--there are also up-down modes that need to be considered. [Hmmm--does one need to subtract 2?]

Many of the new AVR models have like 16 or 32 timer modes. There are at least 3, maybe more, ways to "count".

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.