|
|
View previous topic :: View next topic |
Author |
Message |
E_KARVELAs
Joined: 14 Feb 2007 Posts: 46 Location: Greece & Cyprus
|
TIMER1 1sec int external 32.768 Real-Time Clock |
Posted: Wed Apr 16, 2008 10:12 am |
|
|
HI
I'm posting this code as help for people who need some help starting with Real-Time Clock. Counts seconds, minutes using interrupt TIMER1 with External asynchronous crystal 32.768Khz and 33pF caps on Pins between pins T1OSI (input) and T1OSO (amplifier output). (Look at data sheets).
I had an issue of myself with this code, I couldn't have exactly 1sec interrupt. I was always 1-2 sec forward with my (casio) watch. Searching the forum didn't find exactly where was the issue, until I looked at the datasheet picture and found that the oscillator circuit, shown in Figure 12-3, should be
located as close as possible to the microcontroller, grounded with Vss <<LOOK AT THE PICTURE>> so i give a try and finallly noticed that there was "NO MORE ERROR".
This code uses internal 8MHZ crystal with 32.768 KHz crystal for RTC, flexy_lcd.c driver for 2x16 LCD can be found in the forum.
Code: |
#include <18F2550.h>
#device ICD=TRUE
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOIESO //NO Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN //NO PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES MCLR //Master Clear pin enabled
#FUSES NOLPT1OSC //Timer1 configured for higher power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL12 //Divide By 12(48MHz oscillator input)
#FUSES CPUDIV1
#FUSES NOUSBDIV //NO USB clock source comes from primary oscillator
#FUSES NOVREGEN //NO USB voltage regulator disabled
#use delay(clock=8000000)
#include <flexy_lcd.c>
int sec=0;
int min=0;
int hour=0;
int1 flg=false;
void main(){
enable_interrupts(INT_TIMER1);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_CLK_OUT);
enable_interrupts(GLOBAL);
lcd_init();
setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_ON); //<-- internal 8MHZ crystal with PLL ON 8X4=32MHZ
for(;;){
if(flg==true){
set_timer1(32768); //2^16= 65536/2 = 32768 * 1/32.768Hz <--- (1sec)
setup_timer_1(T1_EXTERNAL|T1_CLK_OUT); // external TIMER1 with
// 32.768Khz ,clock out for oscillator,asynchronus mode
if (++sec>59){
sec=0;
if(++min>59){
min=0;
hour++;
if(++hour>23){
hour=0;
}
}
}
lcd_gotoxy(1,1);
printf(lcd_putc"%02u:%02u:%02u "hour,min,sec);
flg=false;
}
}
}
#int_TIMER1
void TIMER1_isr(void)
{
flg=true;
}
|
_________________ ---- GREECE ---- |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Wed Apr 16, 2008 5:41 pm |
|
|
Use this as the interrupt. This uses 3 instructions that do the following.
1) Enable access to the individual bytes of the timer register
2) Add 32768 to timer1 by setting high bit or timer register
3) Disable access to the individual bytes of the timer register
Code: |
#Byte TMR1H = 0xFCF
#Byte T1CON = 0xFCD
#int_TIMER1
void TIMER1_isr()
{ bit_clear(T1CON,7);
Bit_Set(TMR1H,7);
Bit_Set(T1CON,7);
flg=true;
}
|
and remove this
This will have improved performance and accuracy. There will be no error introduced by setting the timer to 32768 after the timer has incremented to 3 or 4. |
|
|
E_KARVELAs
Joined: 14 Feb 2007 Posts: 46 Location: Greece & Cyprus
|
Thanks goes to Neutone. |
Posted: Thu Apr 17, 2008 8:48 am |
|
|
Code Now improved for more performance and accuracy Thanks to Neutone
Code: |
#include <18F2550.h>
#device ICD=TRUE
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOIESO //NO Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN //NO PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES MCLR //Master Clear pin enabled
#FUSES NOLPT1OSC //Timer1 configured for higher power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL12 //Divide By 12(48MHz oscillator input)
#FUSES CPUDIV1
#FUSES NOUSBDIV //NO USB clock source comes from primary oscillator
#FUSES NOVREGEN //NO USB voltage regulator disabled
#use delay(clock=8000000)
#include <flexy_lcd.c>
#Byte TMR1H = 0xFCF // TIMER1 HIGH BYTE LOOK DATASHEET
#Byte T1CON = 0xFCD //TIMER1 CONFIG REGISTER LOOK DATASHEET
int sec=0;
int min=0;
int hour=0;
int1 flg=false;
void main(){
enable_interrupts(INT_TIMER1);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_CLK_OUT);
enable_interrupts(GLOBAL);
lcd_init();
setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_ON);
//<-- internal 8MHZ crystal with PLL ON 8X4=32MHZ
for(;;){
if(flg==true){
setup_timer_1(T1_EXTERNAL|T1_CLK_OUT); // external TIMER1 with
// 32.768Khz ,clock out for oscillator,asynchronus mode
if (++sec>59){
sec=0;
if(++min>59){
min=0;
hour++;
if(++hour>23){
hour=0;
}
}
}
lcd_gotoxy(1,1);
printf(lcd_putc"%02u:%02u:%02u "hour,min,sec);
flg=false;
}
}
}
#int_TIMER1
void TIMER1_isr() // 2^16= 65536/2 = 32768 * 1/32.768Hz <--- (1sec)
{
bit_clear(T1CON,7); //Enable access to the individual bytes of the timer register
Bit_Set(TMR1H,7); //Add 32768 to timer1 by setting high bit or timer register
Bit_Set(T1CON,7); //Disable access to the individual bytes of the timer register
flg=true;
}
|
_________________ ---- GREECE ---- |
|
|
monkeyman
Joined: 05 Jun 2008 Posts: 18
|
|
Posted: Mon Sep 28, 2009 9:56 am |
|
|
good
but i think there is a problem with hours...
Code: |
if (++sec>59){
sec=0;
if(++min>59){
min=0;
hour++;
if(++hour>23){
hour=0;
}
}
}
|
the hours increment two time for one! |
|
|
omarsito12
Joined: 02 Oct 2009 Posts: 6
|
Re: Thanks goes to Neutone. |
Posted: Tue Dec 01, 2009 7:57 pm |
|
|
E_KARVELAs wrote: | Code Now improved for more performance and accuracy Thanks to Neutone
Code: |
#include <18F2550.h>
#device ICD=TRUE
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOIESO //NO Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN //NO PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES MCLR //Master Clear pin enabled
#FUSES NOLPT1OSC //Timer1 configured for higher power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL12 //Divide By 12(48MHz oscillator input)
#FUSES CPUDIV1
#FUSES NOUSBDIV //NO USB clock source comes from primary oscillator
#FUSES NOVREGEN //NO USB voltage regulator disabled
#use delay(clock=8000000)
#include <flexy_lcd.c>
#Byte TMR1H = 0xFCF // TIMER1 HIGH BYTE LOOK DATASHEET
#Byte T1CON = 0xFCD //TIMER1 CONFIG REGISTER LOOK DATASHEET
int sec=0;
int min=0;
int hour=0;
int1 flg=false;
void main(){
enable_interrupts(INT_TIMER1);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_CLK_OUT);
enable_interrupts(GLOBAL);
lcd_init();
setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_ON);
//<-- internal 8MHZ crystal with PLL ON 8X4=32MHZ
for(;;){
if(flg==true){
setup_timer_1(T1_EXTERNAL|T1_CLK_OUT); // external TIMER1 with
// 32.768Khz ,clock out for oscillator,asynchronus mode
if (++sec>59){
sec=0;
if(++min>59){
min=0;
hour++;
if(++hour>23){
hour=0;
}
}
}
lcd_gotoxy(1,1);
printf(lcd_putc"%02u:%02u:%02u "hour,min,sec);
flg=false;
}
}
}
#int_TIMER1
void TIMER1_isr() // 2^16= 65536/2 = 32768 * 1/32.768Hz <--- (1sec)
{
bit_clear(T1CON,7); //Enable access to the individual bytes of the timer register
Bit_Set(TMR1H,7); //Add 32768 to timer1 by setting high bit or timer register
Bit_Set(T1CON,7); //Disable access to the individual bytes of the timer register
flg=true;
}
|
|
Listen, Hi, I tested this code with Proteus with the pic18f8720 and it doesn't work. What can I do? Please help me. |
|
|
theLion
Joined: 11 Dec 2009 Posts: 1
|
Re: Thanks goes to Neutone. |
Posted: Fri Dec 11, 2009 4:30 pm |
|
|
omarsito12 wrote: | Listen, Hi, I tested this code with Proteus with the pic18f8720 and it doesn't work. What can I do? Please help me. |
I have tested this on Proteus and "no" it doesn't work.. when you simulate the external crystal. The code works - the problem is with Proteus.
You can get around this just by providing a 32768hz clock straight into T1OSI. |
|
|
abbas14
Joined: 05 Sep 2015 Posts: 7
|
|
Posted: Wed Jun 15, 2016 4:34 am |
|
|
Neutone wrote: | Use this as the interrupt. This uses 3 instructions that do the following.
1) Enable access to the individual bytes of the timer register
2) Add 32768 to timer1 by setting high bit or timer register
3) Disable access to the individual bytes of the timer register
Code: |
#Byte TMR1H = 0xFCF
#Byte T1CON = 0xFCD
#int_TIMER1
void TIMER1_isr()
{ bit_clear(T1CON,7);
Bit_Set(TMR1H,7);
Bit_Set(T1CON,7);
flg=true;
}
|
and remove this
This will have improved performance and accuracy. There will be no error introduced by setting the timer to 32768 after the timer has incremented to 3 or 4. |
Hello Neutone!
Why did you disable and enable the 7th bit of T1CON only to set the 7th bit of TMR1H?
I don't understand that.
Doing so will, as per the datasheet, shift the timer clock source to instruction clock (Fosc/4).
TMR1CS<1:0>: Timer1/3/5 Clock Source Select bits
00 = Timer1/3/5 clock source is instruction clock (FOSC/4)
????? _________________ Long Live My Master. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 15, 2016 9:24 am |
|
|
Quote: | Why did you disable and enable the 7th bit of T1CON only to set the 7th bit of TMR1H?
I don't understand that.
Doing so will, as per the datasheet, shift the timer clock source to instruction clock (Fosc/4).
TMR1CS<1:0>: Timer1/3/5 Clock Source Select bits
00 = Timer1/3/5 clock source is instruction clock (FOSC/4) |
<1:0> does not mean bit 7. It means bits 0 and 1.
Look in the PIC data sheet at the T1CON register. You'll see that
bit 7 is the RD16 bit in T1CON. |
|
|
abbas14
Joined: 05 Sep 2015 Posts: 7
|
|
Posted: Wed Jun 15, 2016 10:34 pm |
|
|
PCM programmer wrote: | Quote: | Why did you disable and enable the 7th bit of T1CON only to set the 7th bit of TMR1H?
I don't understand that.
Doing so will, as per the datasheet, shift the timer clock source to instruction clock (Fosc/4).
TMR1CS<1:0>: Timer1/3/5 Clock Source Select bits
00 = Timer1/3/5 clock source is instruction clock (FOSC/4) |
<1:0> does not mean bit 7. It means bits 0 and 1.
Look in the PIC data sheet at the T1CON register. You'll see that
bit 7 is the RD16 bit in T1CON. |
RD16 is bit1.
Or maybe it differs for different uCs.
I am talking about PIC18(L)F2X/4XK22
Look at page number 172 of the datasheet.
By the way, i understand it now. thank you.
One more question: why are you clearing it before setting the 7th bit of TMR1H and then setting it afterwards. the default value of the bit is 0, as per the datasheet. Can't it be left unaltered? because we are not doing any 16-bit read/write operation in this program?
Also, my compiler is showing TMR1H and T1_CLK_OUT as undefined identifier.
I have tried uninstalling and then reinstalling the compiler, but no progress. Can anyone help me out with this? my compiler version is the latest 5.56.
Thanks a lot. _________________ Long Live My Master. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 16, 2016 1:21 am |
|
|
My advice is, open a new thread in the main forum. You have a different,
much newer technology PIC (K22 series). A real-time clock with an
external 32.768KHz crystal is setup differently with your PIC. This thread
is about the older 18F2550 series. |
|
|
abbas14
Joined: 05 Sep 2015 Posts: 7
|
|
Posted: Thu Jun 16, 2016 2:19 am |
|
|
abbas14 wrote: | PCM programmer wrote: | Quote: | Why did you disable and enable the 7th bit of T1CON only to set the 7th bit of TMR1H?
I don't understand that.
Doing so will, as per the datasheet, shift the timer clock source to instruction clock (Fosc/4).
TMR1CS<1:0>: Timer1/3/5 Clock Source Select bits
00 = Timer1/3/5 clock source is instruction clock (FOSC/4) |
<1:0> does not mean bit 7. It means bits 0 and 1.
Look in the PIC data sheet at the T1CON register. You'll see that
bit 7 is the RD16 bit in T1CON. |
RD16 is bit1.
Or maybe it differs for different uCs.
I am talking about PIC18(L)F2X/4XK22
Look at page number 172 of the datasheet.
By the way, i understand it now. thank you.
One more question: why are you clearing it before setting the 7th bit of TMR1H and then setting it afterwards. the default value of the bit is 0, as per the datasheet. Can't it be left unaltered? because we are not doing any 16-bit read/write operation in this program?
Also, my compiler is showing TMR1H and T1_CLK_OUT as undefined identifier.
I have tried uninstalling and then reinstalling the compiler, but no progress. Can anyone help me out with this? my compiler version is the latest 5.56.
Thanks a lot. |
I found the solution.
Instead of T1_CLK_OUT parameter in setup_timer1(), my device header file define T1_ENABLE_SOSC, so i am using that.
and my compiler version does not allows access to individual registers, so i am using set_timer1() instead of bit_set() and bit_clear() functions, as in the original program posted by E_KARVELAs.
Either way, can anyone suggest any way i could use the bit_set() and bit_clear() functions as suggested by Neutone???
Thanks a lot. _________________ Long Live My Master. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|