CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

How to make RTCC more accurate?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Analyzer



Joined: 07 Sep 2003
Posts: 32

View user's profile Send private message

How to make RTCC more accurate?
PostPosted: Sat Dec 20, 2003 2:08 pm     Reply with quote

Hi,

I am a newbie about rtcc interrupt and i referenced ccs example program.This code (below) works but it is not accurate.Because 20M/(4*256*256) = 76,2939453125 and INTS_PER_SECOND is 76! So how can i make it the most accurate? How can i use it?

Thanks.

Analyzer.


#define INTS_PER_SECOND 76 // (20000000/(4*256*256))

byte seconds; // A running seconds counter
byte int_count; // Number of interrupts left before a second has elapsed


#int_rtcc // This function is called every time
void clock_isr() { // the RTCC (timer0) overflows (255->0).
// For this program this is apx 76 times
if(--int_count==0) { // per second.
++seconds;
int_count=INTS_PER_SECOND;
}

}


void main() {

byte start;
byte c;

int_count=INTS_PER_SECOND;
set_timer0(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);

lcd_init();
lcd_clear();
c = 0;

do {
lcd_gotoxy(1,1);
lcd_putc((seconds-start)+48);

} while (TRUE);

}
MGP



Joined: 11 Sep 2003
Posts: 57

View user's profile Send private message

PostPosted: Sat Dec 20, 2003 2:34 pm     Reply with quote

Check out the algorithm here:

http://www.romanblack.com/one_sec.htm

Works great!
Analyzer



Joined: 07 Sep 2003
Posts: 32

View user's profile Send private message

PostPosted: Sat Dec 20, 2003 2:52 pm     Reply with quote

Thank you for your great help.But i can not understand asm code and i am too lazy to get theory and write a new code Laughing

Anywayz, if somebody has an instant ccs c code, please write it here Smile

Analyzer.
Ttelmah
Guest







PostPosted: Sat Dec 20, 2003 3:58 pm     Reply with quote

Analyzer wrote:
Thank you for your great help.But i can not understand asm code and i am too lazy to get theory and write a new code Laughing

Anywayz, if somebody has an instant ccs c code, please write it here Smile

Analyzer.


The simple answer, is to use a crystal that is a binary multiplier. Though you can 'tweak' things to get them closer, if you are working with a crystal frequency that does not evenly divide by the 8bit counter, times the divisor, it'll allways involve extra work. This is why crystals for clock applications, use frequencies like 32768Hz, 4.096MHz, 14.7456MHz etc.. 19.6608MHz, is readily available, and gives a nice 75 count. :-)

Best Wishes
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sat Dec 20, 2003 4:35 pm     Reply with quote

Can you use another timer? Do you have timer1 available? Do you have a CCP still free? If so, respond back and I will show you a way using a CCP int. Another option is to drive timer1 with an external clock. One of those nice frequency values that RJ was referring to.
Analyzer



Joined: 07 Sep 2003
Posts: 32

View user's profile Send private message

PostPosted: Sat Dec 20, 2003 6:05 pm     Reply with quote

Thanks for your help.It is a good idea to change xtall and get nicer values but i have many 4 mhz xtall.I need to use them.

My all timers are free now i only use that code above.I'm using 877 for this.I'm really curious on that "another way" Smile

Analyzer
Guest








What is your Crystal Frequency ?
PostPosted: Sat Dec 20, 2003 8:42 pm     Reply with quote

Analyzer wrote:
Thanks for your help.It is a good idea to change xtall and get nicer values but i have many 4 mhz xtall.I need to use them.

My all timers are free now i only use that code above.I'm using 877 for this.I'm really curious on that "another way" Smile

Analyzer


You started with math showing 20MHz and now your arte using 4MHz !
What is it... ?
Hans Wedemeyer



Joined: 15 Sep 2003
Posts: 226

View user's profile Send private message

Try this...
PostPosted: Sat Dec 20, 2003 9:10 pm     Reply with quote

I don;t have a PIC16 setup at the moment, but form memory this should give a 1 second tick.
hansw

#include <16F877.h>
#device *=16
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT,HS, PUT, NOPROTECT, BROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)

int32 Seconds;
int OneSecondFlag;
int Tick;

/////////////////////////////////////////////
// Using Timer 1 to interrupt every 100mS
// Timer 1 is a 16 bit timer.
// using a 4MHz xtal and Timer1 Prescale = 8
// Timer1 counter sees 8
// for 100mS preload 15536 or 65536-(0.1/(8/4000000))
#int_TIMER1
TIMER1_isr()
{
Set_Timer1(15536);

Tick++;
if( Tick >= 10 )
{
OneSecondFlag++;
Tick=0;
}
}
////////////////////////////////////////////
//
void main()
{
Tick=0;
Seconds=0;
OneSecondFlag=0;

setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
setup_timer_2(T2_DISABLED,0,1);
enable_interrupts(INT_TIMER1);
enable_interrupts(global);


while(1)
{
if( OneSecondFlag > 0 )
{
Seconds++;
printf("%lu\r\n",Seconds);
OneSecondFlag=0;
}
}

}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sat Dec 20, 2003 9:37 pm     Reply with quote

Lets say you are using a 20MHz crystal. The internal speed is 5MHz. This equates to timer1 incrementing every 0.2us with no prescaler assigned. Now we are going to use the CCP1 interrupt to keep track of our time. We will actually be counting 100ths of a second for this example. 100th of a second is 50,000 timer1 ticks (0.01/0.0000002=50000). This will be our CCP1 value.

Code:

#int_ccp1
void ccp1_isr(void)
{
  static count = 0;

  count++;
  if (count == 100)
  {
    count = 0;
    seconds++;
  }
}


We do not need any interrupt for timer1. We just need to set it up

Code:

int seconds=0;

void main(void)
{
  setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  setup_ccp1(CCP_COMPARE_RESET_TIMER);
  // 50000 is how many timer1 ticks for 1/100th of second
  CCP_1 = 50000;
  enable_interrupts(INT_CCP)
  enable_interrupts(GLOBAL);
  while(1)
  {
  }

}



Here is a test program for the PICDEM2 PLUS board. Note that you must modify the lcd.c file according to my previous post regarding using the lcd.c file with the PICDEM board

Code:

#include <18f452.h>
#fuses NOWDT,NOPROTECT,NOLVP,NOWRT,NOEBTR
#DEVICE ICD=TRUE
#use delay (clock=1000000)

#include "lcd.c"
short seconds_flag = FALSE;

void main(void)
{
  int seconds=0;

  setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  setup_ccp1(CCP_COMPARE_RESET_TIMER);
  // 50000 is how many timer1 ticks for 1/100th of second
  CCP_1 = 25000;
//  CCP_1 = 50000;
  enable_interrupts(INT_CCP1);
  enable_interrupts(GLOBAL);
  lcd_init();
  while(1)
  {
    if (seconds_flag)
    {
      seconds_flag = FALSE;
      printf(lcd_putc,"\fElapsed secs %u",seconds++);
    }
  }
}

#int_ccp1
void ccp1_isr(void)
{
  static int count = 0;

  count++;
  if (count == 100)
  {
    count = 0;
    seconds_flag = TRUE;
  }
}


Now the beauty of using the CCP with such a large value is that I could adjust any error due to tolerances with the crystal. At 20MHz, my resolution is 200ns. At 4MHz, I still have millisecond resolution.
dyeatman



Joined: 06 Sep 2003
Posts: 1912
Location: Norman, OK

View user's profile Send private message

RTCC Accuracy
PostPosted: Sun Dec 21, 2003 8:44 am     Reply with quote

All this to avoid buying a 90 cent crystal.... what a waste of time......sigh...Sad

At some point you can cut your losses and save your self a LOT of time!

I had lot of 4MHZ stuff too. But I bit the bullet and started with about 20 of the half can 18.432MHZ oscillators for $1 apiece.

The benefits:
They are very stable and reliable in all environments.
They give me exact RS232 speeds and frequency divides
No Oscillator startup/loading hassles
Less component count
Uses about the same real estate.
Oscillator does not have to be as close a possible to the PIC.
Can be socketed and the frequency changed in seconds. (I always use sockets)
etc...etc...

I have used them in all my designs ever since. The 4MHZ xtals/capacitors and resonators are still sitting in the drawer and suppose they always will be....

something to think about... Smile
Analyzer



Joined: 07 Sep 2003
Posts: 32

View user's profile Send private message

PostPosted: Sun Dec 21, 2003 11:54 am     Reply with quote

Thank you for all your replies.I especially want to thank to code senders.I will try all codes and sim in proteus.I agree to buy new xtalls, i'm totally aware of all benefits but this will be a part of production and i have MANY 4 mhz xtalls Smile and want to spend them.
I will test all and report here.

Thank you again.
KerryW
Guest







Try this:
PostPosted: Sun Dec 21, 2003 12:24 pm     Reply with quote

#define INTS_PER_SECOND 76 // (20000000/(4*256*256))

byte seconds; // A running seconds counter
byte int_count; // Number of interrupts left before a second has elapsed
int32 count;

#int_rtcc // This function is called every time
void clock_isr() { // the RTCC (timer0) overflows (255->0).
count = count + 65536;
if(count>5000000)
{
seconds++;
count = count - 5000000;
}

// For this program this is apx 76 times
//if(--int_count==0) { // per second.
//++seconds;
//int_count=INTS_PER_SECOND;
}

}


void main() {

byte start;
byte c;

int_count=INTS_PER_SECOND;
set_timer0(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);

lcd_init();
lcd_clear();
c = 0;

do {
lcd_gotoxy(1,1);
lcd_putc((seconds-start)+48);

} while (TRUE);

}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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