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

Calculating correct seconds value
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Prasapty
Guest







PostPosted: Mon Jun 13, 2005 3:11 am     Reply with quote

Code test with internal HS on 8 MHZ:

Code:

#include <16F877.h>
#use delay(clock=8000000)
#fuses HS, NOWDT, PUT

#include "LCD.C"


int sec,min,hour;
int8 int_count = 61;

#INT_TIMER1             
void clock_isr()
{       
 int_count--;
 if ((int_count==0) || (int_count==31))
 {     
  sec++;

  if (int_count==0)
   int_count = 61;
     
  if(sec==60)
  {
   sec=0;
   min++;
   if (min==60)
   {
    min=0;
    hour++;
   }
  }
 }
}


void main()
{
    int i;
    sec=0;

    setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
    enable_interrupts(INT_TIMER1);
    enable_interrupts(GLOBAL);

    lcd_init();

 while(TRUE)
 {      
      printf(lcd_putc,"\f%u",sec);
               delay_ms(300);
 }   
}
Mark



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

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

PostPosted: Mon Jun 13, 2005 6:03 am     Reply with quote

Do you have a crystal connected to the PIC? What value is printed on it? Have you looked at the signal with an o'scope? You might toggle a pin in the main loop (just that nothing else) and see what the timing is.
Prasapty
Guest







PostPosted: Mon Jun 13, 2005 7:05 am     Reply with quote

No i dont have cristal connected to pic.

The interessting thing happens when i devide the "real calculated time" ( 30.51 ) with 2.

I get 15.258 which is 0.258 too much but the timer is counting allmost CORRECT ( with this 0.258 delay).


If i set timer on this way then im loosing cca 1 second in 10 seconds count and that is 2.4 hours per day !

I have no clue way is this calculation going backwards ?
Could this have something with clock_isr().

Code:

#INT_TIMER1             
void clock_isr()
 {         
   if(--int_count==0)
 {     
     ++sec;
     int_count = 15;
     
    if(sec==60){
      sec=0;
      min++;
     
      }
    if(min==60){
    min=0;
         hour++;
      }
   
      }
}
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Jun 13, 2005 7:23 am     Reply with quote

Quote:
No i dont have cristal connected to pic.
Then what other mechanism do you use to generate the clock signal?

What is the exact type number printed on your chip? For example, the PIC16F87x-04 is only specified up to 4MHz.
valemike
Guest







PostPosted: Mon Jun 13, 2005 8:47 am     Reply with quote

ckielstra wrote:
Quote:
No i dont have cristal connected to pic.
Then what other mechanism do you use to generate the clock signal?

What is the exact type number printed on your chip? For example, the PIC16F87x-04 is only specified up to 4MHz.


Don't you have to use something like INTRC in the #fuses statement if you are using the internal oscillator? I'm surprised your program is even running when you use HS.
Ttelmah
Guest







PostPosted: Mon Jun 13, 2005 9:05 am     Reply with quote

The 16F87x models, do not even have an internal oscillator. They support external clock input, crystal, or resistor/capacitor oscillators only. The chip would not run unless one of these is present, so the poster must have one, and I'd strongly suspect the frequency is not the 8MHz that they think...

Best Wishes
Prasapty
Guest







PostPosted: Mon Jun 13, 2005 1:16 pm     Reply with quote

I have used different hardware in the past ( with internal and external osc ).

If i would use external osc with this chip i suppose i can get the right counting, but it looks like i have selected wrong chip.

IF SOMEONE OF YOU GUYS WOULD HAVE INTERNAL OSC ON 8 MHZ (it doesent mattter which chip ( running on 16 bit timer) )
HOW WOULD YOU DO THAT... IS THE MATH RIGHT OR NOT ?.
valemike
Guest







PostPosted: Mon Jun 13, 2005 2:55 pm     Reply with quote

Prasapty wrote:
IF SOMEONE OF YOU GUYS WOULD HAVE INTERNAL OSC ON 8 MHZ (it doesent mattter which chip ( running on 16 bit timer) )
HOW WOULD YOU DO THAT... IS THE MATH RIGHT OR NOT ?.


If your observed timing is not right, then your math is wrong.
valemike
Guest







PostPosted: Mon Jun 13, 2005 3:03 pm     Reply with quote

valemike wrote:
Prasapty wrote:
IF SOMEONE OF YOU GUYS WOULD HAVE INTERNAL OSC ON 8 MHZ (it doesent mattter which chip ( running on 16 bit timer) )
HOW WOULD YOU DO THAT... IS THE MATH RIGHT OR NOT ?.


If your observed timing is not right, then your math is wrong.


In my application,
I have 8MHz running off an external crystal, and my

#define INTS_PER_SECOND 30

while my setup_timer_1() statement is:
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);

Are you confusing "T1_INTERNAL" with an internal oscillator? In both of our uses, this T1_INTERNAL means it is using the processor clock, which is your crystal frequency / 4.Your math is right if you are truly using an 8MHz crystal. Otherwise your math is wrong, and so is your #use delay() statement. Please go look at at your circuit board and tell us the value of your crystal, or whatever component it is that is connected to pins OSC1 and OSC2.
Mark



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

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

PostPosted: Mon Jun 13, 2005 6:22 pm     Reply with quote

Math is right that's why I asked about the osc. RTFDS Smile
valemike
Guest







PostPosted: Tue Jun 14, 2005 5:38 am     Reply with quote

You know what, i think the ISR should be minimal and just be:

Code:

#INT_TIMER1                        // This function is called every time
void clock_isr()                   // timer 1 overflows (65535->0), which is
{                                   // approximately 30 times per second for
    if(--int_count==0)             // this program.
    {
        ++seconds;
        int_count = INTS_PER_SECOND;
    }   
}


All the other math such as modulo-60 stuff should be left outside in the main loop.
Guest
Guest







PostPosted: Tue Jun 14, 2005 1:52 pm     Reply with quote

This a bit off the topic... i someone knows ...

How to define the right calculation
( im doing the same thing that the original poster has send (RTC))
but with external LP on 32 KHZ and TIMER1 (16 bit ).

If i calculate this i get very small values (0. something ).

How to define this in the ints_per_seconds part?

p.s. i have to use timer1
valemike
Guest







PostPosted: Tue Jun 14, 2005 2:18 pm     Reply with quote

After 32768 counts (that's 0x8000 in hex), you'll have exactly one second.

I guess you'd use "T1_EXTERNAL" rather than "T1_INTERNAL" in your setup_timer_1() function.
valemike
Guest







PostPosted: Tue Jun 14, 2005 2:26 pm     Reply with quote

setup_timer_1(T1_EXTERNAL | T1_DIV_2)

I think you will get exactly one overflow out of this; that's the reason why they make 32768 hertz clocks.

so in your isr:

clock_isr()
{
seconds++;
}

That's it, i think.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Jun 14, 2005 4:24 pm     Reply with quote

Quote:
setup_timer_1(T1_EXTERNAL | T1_DIV_2)

I think you will get exactly one overflow out of this; that's the reason why they make 32768 hertz clocks.
At 32768Hz this setup will give you an interrupt exactly every 4 seconds, not every second. Instead of dividing the clockpulses by two you would need a clock multiplier in order to get an interrupt every second, too bad this doesn't exist....

Can't you use the 8-bit timer0? Timer0 is 8-bit instead of 16-bit allowing a 128:1 prescaler setting (128 * 256 = 32768)
setup_timer_0(RTCC_8_BIT | RTCC_EXT_L_TO_H | RTCC_DIV_128)

Another option to use timer1 is to preset the timer register to a pre-calculated value which causes the timer to overflow sooner. For example set the timer1 value to 32768 with a prescaler of 1:1.
Code:
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1)
set_timer1( get_timer1() + 32786);

A small problem here is that it is difficult to get an accurate clock because of the timing error introduced between reading the time and setting the new value. Looking at the generated assembly code you can count the number of clock cycles to correct for.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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