Lowering power consumption with timer init problem

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

Hi,

I am using a at90can32 controller. I use AVRGCC and avrstudio.
Optimizer is set to -Os and the CLKDIV fuse is not set so the system clock is equal to my 8Mhz external crystal. I use the FUSE sut_cksel = Ext. Crystal Osc. 3.0-8.0 MHz; Start-up time: 258 CK + 65 ms.

I have checked that my CLKPS setting to /256 is working correctly.

void changeSystemClock()
{ 
   cli();
   CLKPR = (1 << CLKPCE); 	// enable a change to CLKPR 
   CLKPR = (1 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); 		// set the CLKDIV to 256 taking 8Mhz to 31,25kHz
   sei();
}

The main issue as I could see it is the timer1 interupt init for this mode. I use the following init of my timer to achive 1ms interrupt.

void timer1Init(void)
{
	//****8.00Mhz
	TCCR1A = (0 << WGM11) | (0 << WGM10); 
	TCCR1B = (0 << WGM13) | (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10);					// set for clock/1 as counter input
	OCR1AH = 0x1F;
	OCR1AL = 0x40;	
	// Timer 0 interrupt init
	TIMSK1 = 1 << OCIE1A;
}

void timer1LowPowerInit()
{	
	TCCR1A = (0 << WGM11) | (0 << WGM10); 
	TCCR1B = (0 << WGM13) | (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10);					// set for clock/1 as counter input
	OCR1AH = 0x00;
	OCR1AL = 0x1F;
	// Timer 0 interrupt init
	TIMSK1 = 1 << OCIE1A;
}

What I achive with the timer1LowPowerInit function is a timer interrupt approx each 3,5mS but I want it to be each 1mS.

What do I do wrong?

Br Leif G

Last Edited: Thu. Feb 24, 2011 - 11:36 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is this the wrong forum for this type of issue? Is there other forum to use?

Br Leif G

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

avrcalc certainly agrees that for 1.08ms on 8MHz with a /256 prescaler the value is 0x1F but (I can't be bothered to look it up) which WGM mode is it that you are using there? Is it CTC or something else?

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

Thanks for the reply. Yes it is CTC.

Br Leif G

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

Then the implication would appear to be that the CPU is running ~4 timers slower than you think it is. I cannot see an immediate reason in the code as CLKPS3 is correct for /256 and by writing to CLKPR you over-rule any setting of the CLKDIV8 fuse. Could it be that it's really a 2MHz crystal?

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

It's not connected to the WinAVR 4:1 _delay issue by any chance? Just a random thought.

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

I can verify that I use a 8Mhz crystal. I have also tried CLKPS equal to /8 (1Mhz) and /32 (250khz) and with the correct setting for the timer ocr reg it worked and the 1ms interrupt is maintained, but CLKPS below this is giving me a incorrect timer interrupt.

Br Leif G

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

I am not familiar to the WinAvr 4:1 issue. I am actual not sure how I could read the version of the current Win Avr install. The folder is named as follow: WinAVR-20100110.

Br Leif G

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

Forget that - I'm afraid Greg is wrong on this occasion. The issue he's referring to is to do with software delay loops, nothing to do with CPUs/timers running at the wrong speed.

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

Quote:
Just a random thought.
A simple 'No' would have done :)

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

Ok. Thanks for all reply and suggestions. I could by the way not figure out this issue, which I find a little bit stange. I have therefore decided to do a small change to my fw. I discovered that if I Changed my Timer prescaler to /8 and the ocr reg value = 3907 which generate a 1 sec interupt insted of 1 ms everything is working. And so fare I do not need a 1ms timer interrupt while in a low power mode.

Br Leif G

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

Still, it would be interesting to discover what causes that instability. Happy you've found a work round though.

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

I aggree. I really want to figure it out. I am not happy with spending lot of time without solving the problem.

Br Leif G

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

Quote:

What I achive with the timer1LowPowerInit function is a timer interrupt approx each 3,5mS but I want it to be each 1mS.

What do I do wrong?


If I had to guess from what has been posted above (1 second works OK; 1ms takes 3+ms), I'd say that the ISR is taking--3+ms.

Perhaps something like sending several UART characters in polled mode?

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

This is my Timer ISR

SIGNAL(SIG_OUTPUT_COMPARE1A)
{
	//reload for 1ms ticks	
	ms_tick	= true;			
	msTimer++;	
	msTimerChar++;
	uartPort.uartTimeout++;
					
	if(uartPort.uartTimeout == 100)
	{			
		uartPort.foreground_rx_head = uartPort.RxHead;	//Update foreground pointer		
	}
	else if(uartPort.uartTimeout >= 200)
	{									
		uartPort.uartTimeout = 200;
	}
 

	if(delayTimer)
		delayTimer--;

	if(low_power_mode == true)
	{
		secTimer++;	
		total_runtime++;
	}
	else if((msTimer - sec_count) >= 1000)
	{
		sec_count = msTimer;	
		sec_tick = true;
		secTimer++;
		total_runtime++;
	}
}

In this mode I have disabled uarts, adc, different periferal and other interrupt sourches. You anyway gave me an idea. with this low clock sourch Everything is ofcourse slowed down a lot. After reading the amount of instructions I easy see that this function is usin a lot more time than 1ms. Ill do some tests. Thanks for the tips.

Br Leif G

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

Nice catch Lee :)

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

Suggestion: Run like heck (e.g. your 8MHz), and make a "pass" through your main loop. Then do a simple IDLE sleep. You will be awakened the next timer tick.

(I'd typically go to deeper sleep, and sleep for a longer time--is 1ms resolution really necessary? But anyway, when you compare the numbers with a modern AVR P/PA model you might be surprised about the total power consumption.)

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.