View previous topic :: View next topic |
Author |
Message |
ritchie
Joined: 13 Sep 2003 Posts: 87
|
How to setup timer0 for 1second tick |
Posted: Mon Dec 29, 2003 12:37 am |
|
|
Hello,
Can anybody in the community who can provide me info on how can I setup timer0 interrupt for a 1 second tick?
The target chip is PIC18F452 at 20MHz clock.
I'll appreciate any help... please do include math computation.
Thank u. |
|
|
Ttelmah Guest
|
Re: How to setup timer0 for 1second tick |
Posted: Mon Dec 29, 2003 3:31 am |
|
|
ritchie wrote: | Hello,
Can anybody in the community who can provide me info on how can I setup timer0 interrupt for a 1 second tick?
The target chip is PIC18F452 at 20MHz clock.
I'll appreciate any help... please do include math computation.
Thank u. |
You can't, without an external clock.
Timer0, counts (at it's slowest), at Fosc/(4*128), and generates an interrupt every 256 counts. Hence the maximum divisor between interrupts, is (4*128*256)=131072
So you can't get the timer to give a one second 'tick'. However you can use a software 'tick'. If you look at the thread 'need help on timer0', you will see how a software counter can be used to give the required effect.
Best Wishes |
|
|
Ttelmah Guest
|
Re: How to setup timer0 for 1second tick |
Posted: Mon Dec 29, 2003 5:39 am |
|
|
Ttelmah wrote: | ritchie wrote: | Hello,
Can anybody in the community who can provide me info on how can I setup timer0 interrupt for a 1 second tick?
The target chip is PIC18F452 at 20MHz clock.
I'll appreciate any help... please do include math computation.
Thank u. |
You can't, without an external clock.
Timer0, counts (at it's slowest), at Fosc/(4*128), and generates an interrupt every 256 counts. Hence the maximum divisor between interrupts, is (4*128*256)=131072
So you can't get the timer to give a one second 'tick'. However you can use a software 'tick'. If you look at the thread 'need help on timer0', you will see how a software counter can be used to give the required effect.
Best Wishes |
Ongoing (reading the question again...), I realise you are using a 18F452, which supports a 16bit timer0. You therefore can reach the required divisor, _but_ will still have to deal with the problem of adjusting the count to deal with the fact that 20000000/(4*128*65536), is slower than 1/sec...
You would need something like:
Code: |
setup_counters(RTCC_INTERNAL,RTCC_DIV_128);
enable_interrupts(int_timer0);
enable_interrupts(GLOBAL);
in the main (which will default to 16bit mode), then an interrupt handler, with something like:
#define SEC_OFFSET (26473l)
int1 toggle=0;
#int_timer0
timer0_isr() {
if (toggle) {
toggle=0;
set_rtcc(get_rtcc() + SEC_OFFSET);
}
else {
toggle=1;
set_rtcc(get_rtcc() + (SEC_OFFSET+1));
}
}
|
The interrupt code, moves the counter forwards by 26473/26474 on alternate calls, which gives a count between calls of:
(65536-26473.5)*4*128 = 20000000
The interrupt, will be in error by +/- 256 clocks on alternate calls.
In your main code, simply monitor 'toggle', to see when the clock has ticked.
Best Wishes |
|
|
ritchie
Joined: 13 Sep 2003 Posts: 87
|
Re: How to setup timer0 for 1second tick |
Posted: Mon Dec 29, 2003 4:40 pm |
|
|
Quote: |
Code: |
setup_counters(RTCC_INTERNAL,RTCC_DIV_128);
enable_interrupts(int_timer0);
enable_interrupts(GLOBAL);
in the main (which will default to 16bit mode), then an interrupt handler, with something like:
#define SEC_OFFSET (26473l)
int1 toggle=0;
#int_timer0
timer0_isr() {
if (toggle) {
toggle=0;
set_rtcc(get_rtcc() + SEC_OFFSET);
}
else {
toggle=1;
set_rtcc(get_rtcc() + (SEC_OFFSET+1));
}
}
|
|
#define SEC_OFFSET (26473l) ---> wat this stands for? Is this a constant definition or a macro?
Thanx |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Dec 29, 2003 7:20 pm |
|
|
Constant definition. The 'l' is a lower case 'L' which tells the compiler how to handle the constant. The "()" are just a good practice. |
|
|
ritchie
Joined: 13 Sep 2003 Posts: 87
|
|
Posted: Mon Dec 29, 2003 7:40 pm |
|
|
Hello der,
Using the code snippet provided by Ttelmah... I can display a second count on the LCD but I notice that sometimes the counting is fast and slow?
Is this normal? or maybe due to the SEC-OFFSET thing define in the code?
Is this code possible for making a real-time clock which says the time and date?
Comments please?
==================
Code: |
#include <18F452.h> // Target PIC Microcontroller IC
#device ICD=TRUE
#fuses HS,NOPROTECT,NOWDT // PIC MCU Configuration
#use delay(clock=20000000) // 20MHz Crystal clock speed
#include <LCD.C> // LCD routines are here
#define SEC_OFFSET (26473l)
int1 toggle = 0 ;
int8 seconds = 0 ;
#int_timer0
timer0_isr()
{
if (toggle) // toggle=1
{
toggle=0;
seconds++;
set_timer0(get_timer0()+SEC_OFFSET);
}
else // toggle=0
{
toggle=1;
set_timer0(get_timer0()+(SEC_OFFSET+1));
}
}
main()
{
lcd_init();
setup_counters(RTCC_INTERNAL,RTCC_DIV_128);
enable_interrupts(int_timer0);
enable_interrupts(GLOBAL);
while (TRUE)
{
if (toggle)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"%02u",seconds);
if (seconds == 60) seconds=0;
}
}
}
|
if not what other option to undertake or maybe a snippet for a rela-time clock?
Thank you. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: How to setup timer0 for 1second tick |
Posted: Tue Dec 30, 2003 9:35 am |
|
|
ritchie wrote: | Hello,
Can anybody in the community who can provide me info on how can I setup timer0 interrupt for a 1 second tick?
The target chip is PIC18F452 at 20MHz clock.
I'll appreciate any help... please do include math computation.
Thank u. |
timer0 (16 bit mode w/no prescaler) interrupts every 65536 instruction cycles
20MHz crystle = 5Mega Instructions per second
5Mips = 76.2939453125 interrupts of timer 0 per second
Interrupts occur every 0.0131072 seconds
Maximum jitter in second reporting is 13mS
Long term drift is that of the chips oscillator.
Code: |
Int32 Ticker;
#int_TIMER0
void TIMER0_isr()
{ Ticker -= 65536;
if ( Ticker < 65536)
{ Ticker += 5000000;
second++;
}
}
|
|
|
|
|