unable to produce exact 1sec using timer1 on atmega88PA

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

Hi i am trying to configure timer1 for exact sec when i use this code i am getting less than a sec .(910 millisec).Kindly guide me how can i configure for exact 1sec.

#ifndef F_CPU
#define F_CPU 1000000UL       
#endif


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


int main(void)
{
	
	
	DDRC|=(1<<DDC5);
	

	
	_delay_ms(1000);  

	
	PORTC|=(1<<PC5);
	
	OCR1A = 15624;  //Count for 1sec

	TCCR1B |= (1 << WGM12);
	// Mode 4, CTC on OCR1A

	TIMSK1 |= (1 << OCIE1A);
	//Set interrupt on compare match

	TCCR1B |= (1 << CS11) | (1 << CS10);
	// set prescaler to 64 and start the timer


	sei();
	// enable interrupts


	while (1);
	{
		// we have a working Timer
	}
}

ISR (TIMER1_COMPA_vect)
{
	// action to be done after 1sec LED goes off
	
	PORTC&=~(1<<PC5);
}

 

Thanks

Last Edited: Sun. Apr 12, 2015 - 01:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It may just be me.    I am happier with concise statements (with terse comments)

	OCR1A = (F_CPU / 64) - 1;            //15624;  //Count for 1sec
	TCCR1A = 0;                          // no COM bits
	TCCR1B = (1 << WGM12) | (3 << CS10); // Mode 4, CTC on OCR1A, div64
	TIMSK1 |= (1 << OCIE1A);             //Set interrupt on compare match

Quite honestly,   it is the same as your code.

 

If your LED is weird active-high,   it is on for 1 second at start-up.    Then turns off at the first interrupt.

If it is regular active-low,  it is off for 1 second,   and then on permanently.

 

It is very unusual to have a 1MHz crystal.    And if you do have one,    the clock fuses must be set correctly.   e.g. for a XTAL and no CLKDIV8.

 

David.

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

I was going to ask how long

 

 _delay_ms(1000);  

takes?

 

David

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

If you're using the internal oscillator (its not a crystal) then 0.9 secs is within the 10% spec. Solution? Use a crystal or fudge the timer value to suit. Note: the internal oscillator varies with temperature and voltage.

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

What clock are you using? 

 

How are you measuring the time?

Why don't you toggle a pin and measure it with an oscilloscope/counter to check the frequency?

 

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

Not everyone has a sophisticated oscilloscope.

 

David Flippers has suggested a good approach:   i.e. count some blinks with _delay_ms(1000) and measure them with your wristwatch.

 

IMHO,   anyone that writes 'catch-all' code like this requires shooting:

#ifndef F_CPU
#define F_CPU 1000000UL        /*1MHz crystal oscillator */
#endif

especially authors of GCC library code !!!

 

You should #define F_CPU is one place.    If there is a re-definition,   you get a Warning.

 

Using 'catch-all' sequences means you get no Warning.   You don't know what value is in use.

 

DAvid.

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

david.prentice wrote:
Not everyone has a sophisticated oscilloscope.

Doesn't need to be sophisticated just to measure a 1s pulse!

 

Quote:
David Flippers has suggested a good approach:   i.e. count some blinks with _delay_ms(1000) and measure them with your wristwatch.

But is that likely to give much better accuracy that 10% - which is about the error that the OP reported ... ?

 

Quote:
IMHO,   anyone that writes 'catch-all' code like this requires shooting:

#ifndef F_CPU
#define F_CPU 1000000UL        /*1MHz crystal oscillator */
#endif

Agreed!

 

If you're going to have a catcher, make it something useful like:

#ifndef F_CPU
#error "F_CPU Must be defined to the actual CPU frequency - don't forget Fuses, Prescaler, etc!"
#endif

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But is that likely to give much better accuracy that 10% - which is about the error that the OP reported ... ?

It will tell you if it is consistent or not.

 

David  

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

In elementary school, the teachers tell all the little boys and girls that "There is no such thing as a stupid question". If a dude knows how to program the avr, he should know how to look up timer fuses in the datasheet pdf. It clearly states in several places that the darn intenal oscillator is a silicon R and a silicon C and both of those boogers change value with temperature JUST LIKE  A SILICON DIODE. If you program the avr to be a precise chronometer, the only place where it will be accurate is in a tightly temperature controlled room.

 

Imagecraft compiler user

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

Not everyone has a sophisticated oscilloscope.

How true.

 

Yet the OP stated that his timer was giving him a 910 mSec Period.

So one might assume that the OP either has an O'Scope, or a Freq Counter.

 

As asked above,

 

What is the clock source for the uC?

 

How accurate do you want it to be? (i.e. What is "exact?, +/- 1mSec,  +/- 1 uSec, etc.)

 

JC 

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

Yes,   the OP must have some sort of sophisticated equipment.   I can't imagine being able to operate a StopWatch so precisely.

 

Since the calculations have been done perfectly,   we can only guess that her AVR is running on the "Internal 8MHz RC divided by 8".

 

Even so,  a 9% error is within the 10% Factory Calibration.   But very bad luck!!!   In practice most chips are within 2%.

Note that the calibration takes place at 3V.   You should expect a +0.75% speed increase at 5V.   (-0.75% decrease in period)

 

If you really have a 1MHz crystal,   just set the fuses correctly.   Then you will get a perfect 1 second regardless of voltage or temperature.

 

David.

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

Then you will get a perfect 1 second regardless of voltage or temperature.

Which still begs the question:  "What is "Exact"?"

 

Delay 1000 mSec might give one a highly accurate delay.

 

BUT, if "Exact" means +/- uSec's of fractions thereof, then the loop overhead to call the delay routine has to me taken into consideration.

(Push umpteen registers, pop umpteen registers, etc.)

 

Hard to know how good is good enough when the spec' is a bit lacking.

 

JC 

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

I can't imagine being able to operate a StopWatch so precisely.

Sure you can. Just time 100 blinks and divide.

Regards,
Steve A.

The Board helps those that help themselves.

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

That is why I suggested counting a number of blinks.

 

Operating a stopwatch for a single blink requires  better eyesight and reactions than I possess.

 

David.

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

Which still begs the question:  "What is "Exact"?"

I fear we will not get the answer to that question.  [echos of a current thread requiring an "exact square wave?]

 

Indeed, finding exactly one second may also be such a mission, as I learned from Wikipedia that international time standards are actually a combination and adjusted.  So even the highest time generators cannot do "exactly one second".  lol

 

International Atomic Time (TAI) is the primary international time standard from which other time standards, including UTC, are calculated. TAI is kept by the BIPM (International Bureau of Weights and Measures), and is based on the combined input of many atomic clocks around the world, each corrected for environmental and relativistic effects. It is the primary realisation of Terrestrial Time.

 

http://www.microsemi.com/product...

I guess that OP needs to get one of those "chip scale atomic clocks". 

At two orders of magnitude better accuracy than oven-controlled crystal oscillators (OCXOs) - and up to four orders of magnitude better accuracy than temperature-controlled oscillators (TCXOs) -...

And has the "proper" ;) output:

The Quantum SA.45s CSAC produces two outputs, a 10MHz square wave and 1PPS, both in a CMOS 0V to 3.3V format.

Oh, wait -- never mind.  The one second isn't exact! :(

  •  ±5.0E-11 accuracy at shipment
  • < 5E-12 at  τ = 1 hour short-term stability (Allan Deviation)
  • < 3.0E-10/month aging rate

LOL -- I'm learning more than I probably wanted to on this mission.  Some of you might find this article interesting; I did:

http://tf.nist.gov/general/pdf/2...

108 March 2010

Horological Journal

How Accurate is a Radio Controlled Clock?

by Michael A Lombardi.

 

"Does Anybody Really Know What Time It Is?" -- Chicago Transit Authority, 1970

 

As I was walking down the street one day
A man came up to me and asked me what the time was that was
On my watch, yeah
And I said
Does anybody really know what time it is
I don't
Does anybody really care
Care
If so I can't imagine why
About time
We've all got time enough to cry
Oh no, no

 

 

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.

Last Edited: Fri. Apr 10, 2015 - 07:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for response with this code  i am measuring for 30 MINS i am getting 30 mins in stop watch for the count 1854 instead if 1800 count this much varaiance (54) is coming i am using crystal frequency  1MHZ Kindly guide me to get accurate value.

#ifndef F_CPU
#define F_CPU 1000000UL        /*1MHz crystal oscillator */
#endif


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


int val=0;

int main(void)
{
	
	
	DDRC|=(1<<DDC5);
	
	
	
	_delay_ms(1000);

	
	PORTC|=(1<<PC5);
	
	
	OCR1A = 15624;
	 //Count for 1sec

	TCCR1B |= (1 << WGM12);
	// Mode 4, CTC on OCR1A

	TIMSK1 |= (1 << OCIE1A);
	//Set interrupt on compare match

	TCCR1B |= (1 << CS11) | (1 << CS10);
	// set prescaler to 64 and start the timer
	
	


	sei();
	// enable interrupts


	while (1);
	{
		// we have a working Timer
	}
}

ISR (TIMER1_COMPA_vect)
{
	// action to be done every 30MINS LED off
	val++;
	if(val==1854)
	{
	
		PORTC&=~(1<<PC5);
		
	}
	
}

 

Last Edited: Fri. Apr 10, 2015 - 07:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
"Does Anybody Really Know What Time It Is?"

 

The Famous Eccles does: https://www.youtube.com/watch?v=...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As mentioned, it would be uncommon to have a 1MHz crystal oscillator.  you are sure you have one?  Picture or part number?

 

[edit] And you are sure that you have set the fuses to use this external clock source?  And turned off the CKDIV8 fuse?  (i see no manipulation of CLKPR in your posted code.)

 

Then tell what value load capacitors you have mounted.

 

I don't understand about the "1854" in your code...  But in any case you appear to be 3% off from your nominal value and a real, suitable, crystal with proper capacitors shouldn't be that far off.

 

 

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.

Last Edited: Fri. Apr 10, 2015 - 07:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

samathasan wrote:

Thank you for response with this code  i am measuring for 30 MINS i am getting 30 mins in stop watch for the count 1854 instead if 1800 count this much varaiance (54) is coming i am using crystal frequency  1MHZ Kindly guide me to get accurate value.

Yet your own numbers suggest you are not actually "using crystal frequency  1MHZ"

In situations like this, the size of the error often contains useful information.

Your tests show a 3% variation - that is much more than any off-by-1 counter error, and also much more than any possible crystal circuit error - but it is in the realm of On-Chip-Oscillator tolerance.

Simple sanity tests:

a) Physically remove the crystal. Hold it in your hand, and repeat the tests.

b) With a multi-meter and a fast diode (1N4148, BAW62 etc) at the meter tip,  you can test Crystal oscillator amplitude

   Osc --|>|-- Meter - GND  for +ve swing, and  Osc -- |<| -- Meter -- Vcc for -ve swing.

c) remove the /64 prescale and run at 64Hz then use a PC Sound card to measure the frequency.

(example  http://www.daqarta.com/dw_freq.h... )

 PC sound cards are usually within ~ 200ppm ( Mine is stable, at about 180ppm high from memory)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#ifndef F_CPU
#define F_CPU 1000000UL        /*1MHz crystal oscillator */
#endif

Samasthan,

Just to re-iterate. The lines above only tell the compiler what speed the AVR 'should' be running at - they do nothing to the AVR itself. That value is only used to calculate the _delay().

Again, unless you actually have a physical crystal of 1MHz connected to your AVR, then you don't have a crystal oscillator. The default oscillator in the AVR is a RC oscillator and it is none too accurate. What you're observing is within specification. If you want more precise timing, get yourself a REAL crystal and attach it to the AVR then set the fuses to use it. Or get yourself an Arduino board and not have to worry about such problems.

 

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

Described in msg #9

Imagecraft compiler user

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

sometimes you just gotta punch in the info a couple of times.

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




#ifndef F_CPU
#define F_CPU 8000000UL        
#endif


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


int val=0;
int main(void){
	
	DDRB = (1<<PB0);    //Configure led pin
	
	_delay_ms(500);
	
	PORTB|=(1<<PB0);
	
	//Configure timer in CTC mode
	TCCR1B = (1<<WGM12)|(1<<CS12);    //Enable CTC mode, and set prescaler to 1:256
	OCR1A =  31249;            //sets the desired count
	TIMSK1 = (1<<OCIE1A);        //Enable timer interrupts
	
	sei();    //Enable global interrupts, so our interrupt service routine can be called
	
	for(;;){
		//Our infinite loop, this will remain clean, everything is done in the interrupt
	}
	
	return 0;
}

ISR(TIMER1_COMPA_vect){        //This is our interrupt service routine
	
//	after 30 mins LED to go Off
	val++;
	if(val==3659)    //For 1min
	{
		
		PORTB&=~(1<<PB0);
		
	}
	
}

Hi , 

 

I tried with 8MHz internal Oscillator but the same output is coming for thirty mins count in val=1800 should be ,but if i give  val=1854 then only i can see the timer and time   in stop watch are matching that LED goes off after  30 mins.fuse bits settings kindly find the attachment

Attachment(s): 

Last Edited: Sat. Apr 11, 2015 - 04:50 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The 8MHz internal oscillator is the same as your 1MHz one, so the error is the same. Again, you have two choices - attach an external crystal or fudge your numbers. We can't tell you what number you need to fudge to as every AVR is different!

Last Edited: Sat. Apr 11, 2015 - 02:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi , 

 

I tried ...

Why don't you answer this questions I posed, and others have asked similarly?

 

As mentioned, it would be uncommon to have a 1MHz crystal oscillator.  you are sure you have one?  Picture or part number?

 

[edit] And you are sure that you have set the fuses to use this external clock source?  And turned off the CKDIV8 fuse?  (i see no manipulation of CLKPR in your posted code.)

 

Then tell what value load capacitors you have mounted.

 

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

Samathasan, 

What is the clock source for your microcontroller?

 

The microcontroller has its own Internal clock.

If this is used then no external clock crystal is required.

The internal (RC Oscillator) isn't very accurate, but can be calibrated.

 

Shown below are other options for providing the clock for the microcontroller.

#1 Ceramic Resonator  Usually 3 leads, the center being ground.

It usually has capacitors built into it.

It is inexpensive, and more accurate than the uC's internal clock.

The one shown is 20 MHz.

 

#2 SMD "Crystal"  Also called an Xtal for short.

This is a two lead device. The one shown is 14 MHz.

External capacitors are required.

Crystals use active circuitry inside the chip to make an oscillator, (clock).

 

#3  "Clock Crystal"  These are, by definition, 32.768 kHz.

They are often used in watches, Real Time Clocks, and as a reference clock source.

They, like the other devices shown here, come in different shapes and sizes.

 

#4 & #5 Are both "Crystals"  These are two different packages for 14 MHz crystals.

They are very accurate compare to the other ceramic resonator and the uC's internal RC Oscillator.

They both require external capacitors.

 

#6 External Oscillator   This is a chip which has its own V+ and Ground pins, and outputs a square wave.

This one puts out a 25 MHz clock (square wave) at 3 V.

It uses a By-Pass, (decoupling), cap, 0.1uF, on its V+.

It doesn't otherwise use any capacitors.

 

The Wiki Page below has info on other clock sources, including those with their own temperature and voltage controller built in.

 

Wiki has a page on Crystals, seen here, with lots more info.

 

Note that on AVR Mega and Tiny microcontrollers one has to use the "Fuses" to tell the micro what is being used for the clock source to make the uC run.

On the Xmegas one can set the clock source via software.

 

Some uC's also have a Fuse to divide the clock, (whatever the source), by 8.

This slows the clock down a lot.

 

Some uC's have an internal 32 kHz clock as well as the internal clock that runs at several MHz.

 

SO, what are YOU using as the clock for your microcontroller?

 

JC

 

 

 

 

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

On both your pictures you are using the internal RC oscillator (low fuse 0xE2).    Can you post a picture of the fuses when you think you are using the 1MHz crystal oscillator?

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

Hi 

 

i am using internal oscillator 8MHZ.I dint connect any external oscillator.

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

With the internal RC oscillator you will not get much better than what you have.    It does not matter (a lot) if you use 8MHz or divide it by 8 to 1MHz.   If you want better accuracy you will need an external crystal connected to the XTAL pins.   Looking though the post you never said you had a crystal oscillator but it was in the comment of your first post with code.

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

After nearly 30 posts we're back to where we were at the beginning. If you want readonable timing precision (<100ppm) use a crystal. If you want better, a temperature compensated crystal. Even better, a gps receiver.

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

Hi

 

 

 

Thanks for the response,kindly guide  me for choosing right  external oscillator  ,what are the specifications it  Supposed to be??

 

 

Thanks

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

Read message #26.    It even shows photos of the different crystals and resonators.    Choose photo#4 with a value of 8MHz and two 22pF capacitors.  

 

David. 
 

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

AVRs are pretty forgiving about the crystals you use. As long as it's 1MHz..20MHz and looks something like this:

 

http://www.fpga4fun.com/images/Crystals&Oscillators.jpg

 

The chances are it's going to work. In the case of crystals (two pins) you are also going to need two capacitors to connect each "leg" to "ground. Just pick something 10pF to 20pF and again you should be "in the ball park". If you can find a datasheet for the exact crystal you use it should tell you the exact pF value to use but something will happen with anything in the 10..20pF range and even if it's not quite right the thing will still be orders of magnitude more accurate than using the internal oscillator in the AVR.

 

In the past I have just bought a "bargain bag" of crystals something like this:

 

https://www.sparkfun.com/product...

http://www.ebay.com/itm/9-Value-...

 

That should keep most hobbyists going for years!

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

Thank you