| Author |
Message |
|
|
Posted: Jun 05, 2007 - 12:34 AM |
|

Joined: Dec 14, 2005
Posts: 96
Location: Latvia
|
|
Hi,
I'm making clock with Atmega8 and 32.768kHz crystal connected to TOSCn pins. But it isn't as precise as I expected (+/-10 sec each hour).
The problem is that the time goes too slow, when CTC mode is used, or it goes too fast, when timer overflow is used. Maybe the timer initialization isn't correctly done? Or there is something else?
Thanks!!!
CTC mode
Code:
init_timer:
ldi tempL,(1<<AS2)
out ASSR,tempL
in tempL,ASSR
andi tempL,(1<<TCR2UB)
cpi tempL,0
brne PC-3
ldi tempL,(1<<WGM21)|0x06
out TCCR2,tempL
in tempL,ASSR
andi tempL,(1<<OCR2UB)
cpi tempL,0
brne PC-3
ldi tempL,0x80
out OCR2,tempL
ldi tempL,(1<<OCIE2)
out TIMSK,tempL
ret
Timer overflow
Code:
init_timer:
ldi tempL,(1<<AS2)
out ASSR,tempL
in tempL,ASSR
andi tempL,(1<<TCR2UB)
cpi tempL,0
brne PC-3
ldi tempL,0x05
out TCCR2,tempL
in tempL,ASSR
andi tempL,(1<<TCN2UB)
cpi tempL,0
brne PC-3
ldi tempL,0
out TCNT2,tempL
ldi tempL,(1<<TOIE2)
out TIMSK,tempL
ret
|
|
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 12:42 AM |
|


Joined: Nov 01, 2005
Posts: 6354
Location: Hilversum - the Netherlands
|
|
The 32768 Hz crystals aren't very precise .... 10 ppm for the good ones and 30 ppm for the standard ones. Next to that, they're very sensitive for temperature.
Regarding software: timeroverflow is the standard procedure. 32768 = 2E14 .. so binary division is exactly what you need. |
_________________ Dragon broken ? Or problems with the Parallel Port Programmer ? Scroll down on my projects-page http://www.aplomb.nl/TechStuff/TechStuff.html for tips
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 01:08 AM |
|

Joined: Dec 14, 2005
Posts: 96
Location: Latvia
|
|
Thanks for the fast reply!
But I think there must be some other factor which affects the precision, because 10 seconds each hour is very big error. |
|
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 01:58 AM |
|


Joined: Feb 19, 2001
Posts: 26092
Location: Wisconsin USA
|
|
Without digging through all the datasheets, what tick (period in ms) are you expecting from timer2 in CTC mode? In overflow mode?
According to AVRCalc, an 8-bit timer can't reach a full second with a 32k crystal.
I'd like to see the ISR routines.
What I'd suspect is that you need to subrtact one from your OCR2 value, as both 0 and TOP are counted. And for overflow, by the time you increment TCNT0 one or more ticks have elapsed. You want somthing like TCCNT0 += magicincrementvlaue; instead of TCNT0 = magicincrementvalue; .
Lee
Lee |
|
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 02:16 AM |
|


Joined: Nov 01, 2005
Posts: 6354
Location: Hilversum - the Netherlands
|
|
| Lee wrote:
Quote:
According to AVRCalc, an 8-bit timer can't reach a full second with a 32k crystal.
Hmmm, but my clock does .....
This is BascomAVR-code, clean-cut from my radio-clock (mega32). If there is no proper radio-signal, the RTC takes over ...
Code:
'Timer2 = RealTimeClock
'Set up for 1Hz interrrupt on overflow
Set Assr.as2 'enable watch-xtal
Wait 2 'give watch-xtal time to start ... be gentle
Set Tccr2.cs22
Set Tccr2.cs20 'set for divide by 128 : result 1 Hz
On Ovf2 Rtc_second Nosave
Enable Ovf2 'the 1 Hz interrupt
Timer2 is an 8 bitter, and when pre-scaler set to 128 ...... 128 * 256 = 32768 --> overflow every second
And from there on it's just: counting seconds
Nard |
_________________ Dragon broken ? Or problems with the Parallel Port Programmer ? Scroll down on my projects-page http://www.aplomb.nl/TechStuff/TechStuff.html for tips
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 02:28 AM |
|


Joined: May 26, 2004
Posts: 2538
Location: Las Vegas, Nevada
|
|
| Using Timer 2 with a watch crystal definitely needs trimming. Use a fixed 12pF capacitor on TOSC1 and a 5-25pF trimmer on TOSC2 - that covers the range for most watch crystals. With no capacitors, or ones that are too large, it's quite likely to be off by 10 seconds an hour. |
|
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 02:28 AM |
|


Joined: Feb 19, 2001
Posts: 26092
Location: Wisconsin USA
|
|
|
Quote:
Lee wrote:
Quote:
According to AVRCalc, an 8-bit timer can't reach a full second with a 32k crystal.
Hmmm, but my clock does ..... Twisted Evil
Doh! I set it for 32.768MHz--duh.
Next time I should think. But the rest of it is right--for CTC, you set to 0x7f rather than 0x80, since both ends are counted. (Or whatever with your prescaler.)
For overflow, I'd have to see the ISR.
Lee |
|
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 02:54 AM |
|


Joined: Nov 01, 2005
Posts: 6354
Location: Hilversum - the Netherlands
|
|
Lee, what is the advantage of CTC over OVF ?
Peret: thanks. I made a note of your tip ..... for the next NixNie
Nard |
_________________ Dragon broken ? Or problems with the Parallel Port Programmer ? Scroll down on my projects-page http://www.aplomb.nl/TechStuff/TechStuff.html for tips
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 03:18 AM |
|


Joined: Feb 19, 2001
Posts: 26092
Location: Wisconsin USA
|
|
|
Quote:
Lee, what is the advantage of CTC over OVF ?
Lots, IMO, for these timekeeping apps. With a desired "high" roll-over of a few milliseconds or more, there will never be any jitter or loss in the timekeeping as long as you don't miss a complete tick--in this case a second. With overflow, you only have to be delayed a few [thousand] clock cycles before you lose a tick. With low prescalers and you are adjusting the TCNT, you either need to be clever or you risk adding the wrong amount. And don't even ask me about TCNT = vs. TCNT+= ...
Lee |
|
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 03:50 AM |
|

Joined: Nov 17, 2004
Posts: 13949
Location: Vancouver, BC
|
|
|
Quote:
it's quite likely to be off by 10 seconds an hour.
I hardly think so. That would be accuracy of only 3 part per thousand. 10 seconds in a day, maybe. |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 05:27 AM |
|

Joined: Dec 18, 2001
Posts: 4779
|
|
I hooked a 32768KHz crystal to the ext OSC of the mega8 and used it with this code. As I recall (long time ago) it was arranged for the crystal/timer to interrupt many times per second. This rate was used to keep time of day to a fraction of a second, due to the application. No issue with latency re-loading the timer as I recall because that wasn't done due to the timer mode. Just have to make sure that interrupt latency is never more than the timer interrupt period.
It was accurate to about 30 seconds a week. Ran slow. I tried two different kinds of crystals. Had the recommended capacitors. Adding shunt trim capacitors would make it still slower. Not good enough for me. I went to a DS1307 clock module.
The Interrupt code does nothing with the timer hardware - the mode is to auto-reload on overflow. Reloading the timer in the interrupt code may slow the clock due to variable interrupt latency. All the interrupt code does is modify the date and time of day in RAM as fast as possible, then RETI.
I hope that I recall all this correctly. Dusty memory.
It's an extract from
http://www.avrfreaks.net/index.php?modu ... tem_id=230
Code:
Initialization
const BYTE TCCR2INIT = 2; // 1 == 128 interrupts/sec with 32768Hz crystal
const int TICKSPERSECOND = 128/8; // <<< Change this if TCCR2 initialization is changed
////////////////////////////////////////////////
void timer_init(void)
{
// Timer/Counter0 Clock source: System Clock
// Timer/Counter0 Clock value: Stopped
// Timer/Counter0 Mode: Normal
// Timer/Counter0 Output: Disconnected
OCR0 = 0x0;
TCNT0 = 0x0;
TCCR0 = 0x0;
// Timer/Counter1 Clock source: System Clock
// Timer/Counter1 Clock value: Stopped
// Timer/Counter1 Mode: Normal
// Timer/Counter1 Output: A: Disconnected, B: Disconnected
OCR1AL = 0x0;
OCR1AH = 0x0;
OCR1BL = 0x0;
OCR1BH = 0x0;
TCNT1L = 0x0;
TCNT1H = 0x0;
TCCR1A = 0x0;
TCCR1B = 0x0;
// Timer/Counter 2 initialization
// Clock source: TOSC1 pin
// Clock value: PCK2/128
// Mode: Output Overflow
// OC2 output: Disconnected
// using 327868Hz crystal
TCCR2 =TCCR2INIT; // interrupts per sec
ASSR = (1 << AS2); // AST bit -> use the wired 32768 Hz Xtal
TCNT2=0x00;
TIMSK |= (1 << TOIE2); // Timer2 overflow interrupt
}
|
|
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 10:12 AM |
|


Joined: Nov 01, 2005
Posts: 6354
Location: Hilversum - the Netherlands
|
|
| Lee wrote:
Quote:
With overflow, you only have to be delayed a few [thousand] clock cycles before you lose a tick.
No, no, that overflow-interrupt needs to be serviced within a second to prevent loss. That's why 32.768 kHz (watch)crystals are so great to use for RTC applications.
In case of for instance, a required 1 ms tick, CTC is the way to go. And you are right: put one less in the compare-register than the number of required ticks. As you say, zero is included.
Nard
Edit: btw, I don't touch TCNT2 in this application. Timer2 simply overflows. The interrupt routine updates the variables rtc_seconds and rtc_minutes, and sets a flag for the hours. All other handling takes place in the main loop. |
_________________ Dragon broken ? Or problems with the Parallel Port Programmer ? Scroll down on my projects-page http://www.aplomb.nl/TechStuff/TechStuff.html for tips
Last edited by Plons on Jun 05, 2007 - 11:47 AM; edited 1 time in total
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 11:01 AM |
|

Joined: Dec 14, 2005
Posts: 96
Location: Latvia
|
|
I tried to do as you suggested - to decrease compare value to 0x7F but now the time went too fast.
Here is may ISR routine:
Code:
oc2int:
inc seconds
cpi seconds,60
brne end_int
clr seconds
inc minutes
cpi minutes,60
brne end_int
clr minutes
inc hours
cpi hours,24
brne end_int
clr hours
end_int:
ldi data,12
rcall putchar
mov data,hours
rcall bin_to_bcd
push tempL
mov data,tempH
subi data,-48
rcall putchar
pop data
subi data,-48
rcall putchar
ldi data,':'
rcall putchar
mov data,minutes
rcall bin_to_bcd
push tempL
mov data,tempH
subi data,-48
rcall putchar
pop data
subi data,-48
rcall putchar
ldi data,':'
rcall putchar
mov data,seconds
rcall bin_to_bcd
push tempL
mov data,tempH
subi data,-48
rcall putchar
pop data
subi data,-48
rcall putchar
reti
'putchar' sends 'data' to PC. It is only temporary for debugging. |
|
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 12:00 PM |
|


Joined: Nov 01, 2005
Posts: 6354
Location: Hilversum - the Netherlands
|
|
|
Quote:
but now the time went too fast.
Time flies when you're enjoying yourself (couldn't resist)
Whether you prefer to use CTC or OVF ... that's up to you. Overflow is IMO the way to go. Don't fiddle with TCNT2, just prescale = 128.
I agree with Koschi: 10 seconds per hour means 4 minutes per day. That's way too much. Even for an untrimmed 30 ppm watch-crystal. Atmel tells us that the oscillator for TOSC is a low-power one, and noise must be avoided. Is it possible that your hardware-design is causing the error? Maybe you could post some pictures of the layout.
Two notes on your software: adding comments is a good thing. Not just for us, but for yourself as well. The second one: you are handling a lot of stuff in the interrupt-routine. I suggest you update seconds, minutes (and maybe hours) in the interrupthandler, set a flag, exit, and handle the flag in the main loop: doing the bin to bcd, printing to terminal etc.
Nard |
_________________ Dragon broken ? Or problems with the Parallel Port Programmer ? Scroll down on my projects-page http://www.aplomb.nl/TechStuff/TechStuff.html for tips
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 01:48 PM |
|


Joined: Jul 02, 2005
Posts: 6030
Location: Melbourne, Australia
|
|
|
Plons wrote:
32768 = 2E14
Actually it is 2^15...(that is, 2 multiplied by itself 15 times). |
_________________ Ross McKenzie
ValuSoft
Melbourne Australia
|
| |
|
|
|
|
|
Posted: Jun 05, 2007 - 02:08 PM |
|


Joined: Nov 01, 2005
Posts: 6354
Location: Hilversum - the Netherlands
|
|
|
|
|
|
|
Posted: Jun 05, 2007 - 02:57 PM |
|


Joined: Feb 19, 2001
Posts: 26092
Location: Wisconsin USA
|
|
|
Quote:
No, no, that overflow-interrupt needs to be serviced within a second to prevent loss. That's why 32.768 kHz (watch)crystals are so great to use for RTC applications.
I was considering the general case where exactly 256 counts isn't what is desired.
To OP's situation: not all 32k crystals are created equal, and neither are all AVR models. Some crystals + some AVRs may not need load caps at all, and they may in fact throw it off. There have been a few past threads on this. |
|
|
| |
|
|
|
|
|