View previous topic :: View next topic |
Author |
Message |
Prasapty Guest
|
|
Posted: Mon Jun 13, 2005 3:11 am |
|
|
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
|
|
Posted: Mon Jun 13, 2005 6:03 am |
|
|
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
|
|
Posted: Mon Jun 13, 2005 7:05 am |
|
|
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
|
|
Posted: Mon Jun 13, 2005 7:23 am |
|
|
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
|
|
Posted: Mon Jun 13, 2005 8:47 am |
|
|
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
|
|
Posted: Mon Jun 13, 2005 9:05 am |
|
|
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
|
|
Posted: Mon Jun 13, 2005 1:16 pm |
|
|
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
|
|
Posted: Mon Jun 13, 2005 2:55 pm |
|
|
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
|
|
Posted: Mon Jun 13, 2005 3:03 pm |
|
|
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
|
|
Posted: Mon Jun 13, 2005 6:22 pm |
|
|
Math is right that's why I asked about the osc. RTFDS |
|
|
valemike Guest
|
|
Posted: Tue Jun 14, 2005 5:38 am |
|
|
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
|
|
Posted: Tue Jun 14, 2005 1:52 pm |
|
|
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
|
|
Posted: Tue Jun 14, 2005 2:18 pm |
|
|
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
|
|
Posted: Tue Jun 14, 2005 2:26 pm |
|
|
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
|
|
Posted: Tue Jun 14, 2005 4:24 pm |
|
|
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. |
|
|
|