View previous topic :: View next topic |
Author |
Message |
lucke
Joined: 23 Mar 2017 Posts: 9 Location: Brazil
|
Problem with TIMER0 (PIC16F630) |
Posted: Mon Jul 22, 2019 9:17 pm |
|
|
Hello guys! I am trying to make a clock using PIC16F630 and a CD4511 by multiplexing 7 segment displays. Everything is working except the accuracy of time.
I am using TIMER0 (8 bits), and for overflow I used the equation (I try for 1s interrupt):
t = FOsc/ (4*PreScaler*(256-t0))
FOsc = 4*10^6
PreScaler = 16
t0 = 6 (for exact account)
Doing the math, I got the result:
t = 250
Based on this result, I tried to make the code:
Code: |
#include <16F630.h>
setup_adc_ports(no_analogs);
#FUSES NOPROTECT
#FUSES INTRC_IO
#FUSES NOWDT
#FUSES NOMCLR
#use delay(internal=4000000)
#use FIXED_IO( A_outputs=PIN_A3,PIN_A2,PIN_A1,PIN_A0 )
#use FIXED_IO( C_outputs=PIN_C5,PIN_C4,PIN_C3,PIN_C2,PIN_C1,PIN_C0 )
byte contador = 0;
#INT_TIMER0
void trata_timer0 ()
{
clear_interrupt(INT_TIMER0);
set_timer0(6);
contador++;
if (contador == 250)
{
incSeg(); //when complete 1s
contador = 0;
}
}
void main() {
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);
set_timer0(6);
clear_interrupt(INT_TIMER0);
enable_interrupts (INT_TIMER0);
enable_interrupts (GLOBAL);
While(TRUE){
/*
*/
}
|
(If necessary, I can post the full code)
After some time, he begins to advance the time... What may be happening?
There are some 1 ms delays for multiplexing in the main() function code, inside the loop. Could this be influencing?
Thanks! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Jul 22, 2019 10:50 pm |
|
|
You don't need the clear_interrupt in the handler code. The compiler does
this for you unless you specify 'NOCLEAR'.
I'd have expected it to run slow. It takes time to get into the interupt
so several counts will have happened before it reaches the instruction
setting the timer.
However the big issue is the inaccuracy of the internal timer. For a
5v supply this is only guaranteed to be +/- 5% accurate. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Jul 23, 2019 6:39 am |
|
|
As a rule we don't endorse simulator use.
However, in this case, you could try using the MPLAB simulator tool (MPLAB SIM).
It will assume a perfect oscillator frequency and any errors will be due largely to coding.
I've found that MPLAB SIM does give errors of one or two clock cycles.
You can expect your coding errors to be more than that.
Mike |
|
|
lucke
Joined: 23 Mar 2017 Posts: 9 Location: Brazil
|
|
Posted: Tue Jul 23, 2019 7:14 pm |
|
|
Quote: |
However the big issue is the inaccuracy of the internal timer.
|
If I buy a 4MHz crystal and set the oscillator (like in https://www.ccsinfo.com/newsdesk_info.php?newsPath=ALL&newsdesk_id=164), will the time be accurate?
Code: |
#FUSES XT
#use delay(CLOCK=4000000, CRYSTAL=4000000)
|
Out of curiosity, is the calculation correct? (previous post)
Quote: |
It will assume a perfect oscillator frequency and any errors will be due largely to coding.
|
How could code influence? (A badly done interrupt?)
I went back to studying electronics recently and, for lack of time and money, I'm studying for free time... This is the forum that is helping me the most.. Thank you all for patience. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Wed Jul 24, 2019 12:47 am |
|
|
The fact that you talk about it going wrong 'after a time', suggests that the
issue is actually something in your code. Possibly you are actually doing
something that is changing the timer setup or the oscillator.
With a crystal, it is possible to get accurate times, but not with the code
as posted. If you think about it, time has passed when it gets into the
interrupt and executes the set_timer function. The counts for this _will_ be
lost.
It is better to use one of two approaches:
1) Use a timer that has a hardware reset (timer2). This can be set to reset
on an exact count.
2) Write the code to cope with a non resetting timer. Look in the code
library. There is an RTC using this approach:
<http://www.ccsinfo.com/forum/viewtopic.php?t=26177> |
|
|
|