Timer 1 CTC mode

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

The data sheet specifies the following as the way to do a write to TCNT1 to avoid any interrupt from corrupting the register during a write:

unsigned int TIM16_ReadTCNT1( void )
{
unsigned char sreg;
unsigned int i;
/* Save global interrupt flag */
sreg = SREG;
/* Disable interrupts */
_CLI();
/* Read TCNT1 into i */
i = TCNT1;
/* Restore global interrupt flag */
SREG = sreg;
return

This is a segment of my code and the timer interrupt"

/* Set up & enable Timer/Counter 1 for CTC mode */
	TCCR1B |= (1<<WGM12);	//Set for CTC mode
	OCR1A = 140;	//7ms interrupt

//Timer 1 Interrupt
ISR(TIMER1_COMPA_vect)
{
	OCR0A = 150;
	Stop_Timer1;
	Disable_Timer1_Int;
}

/* ------------------Function Deifinitions----------------------- */
bool Fire(bool t_flag){	
	if( t_flag ){
		if( Trigger == 0 )
		{		
			OCR0A = 75;
			Turn_Off_Brake;
			Set_COMBits;	
			Start_PWM0;	
			t_flag = false;	
			TCNT1 = 0;
			Enable_Timer1_Int;
			Start_Timer1;
		}
	}
	return t_flag;
}

My question is, do I still need to do a global interrupt disable/enable if the only two interrupt sources are PCINT1 which is a higher priority than TIMER1 in CTC mode?

What I am trying to accomplish is a soft start for an electric motor, I want a PWM value of 75 for 7ms then change it to 150 after 7ms. It will stay at 150 until the trigger is let off. So every time I start I want a soft start, which means I need to stop timer1 after I change the PWM and reset it before I start again. I am using Timer0 for the PWM, Timer1 in CTC mode for the 7ms delay and PCINT8 for gearbox position(not shown) in another sub.

Start and Stop Timer1 i'm simply setting and clearing the CS bits as I do with PWM to start and stop it.

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

I don't see any reason for saving SREG or disabling interrupts during an ISR with C unless you are using some strange features of the compiler.

ie sreg is automatically saved and restored and the I bit is off untill you return from the interrupt.

Which chip are you using anyway?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Hmmm, since the AVR hardware does an indivisible read of TCNT1 (and assorted other 16-bit registers) anyway, I can't see the need for stopping interrupts in any case.

The indivisible read is done by reading first the low byte, which latches the high byte at the same time, then reading the latched high byte. Writing works the other way - write high byte, then write low byte, which also writes the latched high byte at the same time.

OK, I can imagine one scenario that causes a problem. Foreground code starts the read process by reading the low byte (high byte gets latched). Interrupt comes along before the latched high byte is read, and disturbs the latched high byte by doing another 16-bit read or write. ISR ends and the latched high byte is no longer valid.

So in general a 16-bit access to TCNT1 doesn't need to be protected, but in the specific case mentioned it does.

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

I'm using an ATMega88PA @ 20MHz. Thanks for the information. Also, is there an interrupt flag I can reset for the timer? When doing a simulation with an extremely low value in OCR1A (0x0A), the interrupt re-occured before it was able to exit the ISR(due to the point at which the code was interrupted as the counter was already at 0x08, so once the interrupt was re-enabled it would jump right back in again. I don't for see using such a low value in many cases, but I think it would be prudent to clear the flag that triggers the interrupt or is that flag cleared when writing 0 to TCNT1?

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

Quote:

but I think it would be prudent to clear the flag that triggers the interrupt or is that flag cleared when writing 0 to TCNT1?

What does the datasheet say in the description of the xxIFx bits for timers?

Why would you want to interrupt at such a frequent interval?

Calling functions from an ISR doesn't generally lead to a lean and mean one.

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

I'm not calling functions from an ISR, this was just a very specific case I came accross and as I said I doubt I would ever set an interrupt so frequently. In any case I figured it out, thanks for the help though.