View previous topic :: View next topic |
Author |
Message |
rookiee
Joined: 31 Aug 2019 Posts: 5
|
Timer1 using 32kHz external crystal |
Posted: Sat Aug 31, 2019 10:07 am |
|
|
Hi everyone, I am planning to use the 32k external crystal for timer1 to keep a low power and provide a more accurate clock. However, I encounter some problem in my code and looking for some advice. I had the following setup and using a LED for testing and the interrupt seems not triggering.
Code: |
#include <16F15376.h>
#device ADC=10
#use delay(clock=16MHz)
#define LED pin_B0
#INT_TIMER1
void timer1_isr(void)
{
output_toggle(LED);
set_timer1(65535);
clear_interrupt(INT_TIMER1);
}
void main()
{
enable_interrupts(INT_TIMER1); // Enable Timer1 interrupt
enable_interrupts(GLOBAL); // Enable global interrupts
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_8);
set_timer1(65535);
clear_interrupt(INT_TIMER1); // Clear Timer1 interrupt
while(1)
{}
}
|
Also I would like to confirm if the above set up could me get a 0.001s for timer overflow. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Sat Aug 31, 2019 10:30 am |
|
|
65535, is the maximum count that the timer can hold. It's next count is
0 and the interrupt will occur. So just one count later the interrupt will occur.
Now, have you done a simple test to verify the chip is running?. I doubt if
it is. You are not telling it 'where' the 16Mhz is to come from. The default
oscillator setting assumes an external oscillator. So the chip won't run.
You can't actually generate a 1mSec 'tick' with a 32768Hz crystal. Think
about it 32.768 counts. However:
Code: |
#include <16F15376.h>
#device ADC=10
#use delay(INTERNAL=16MHz)
//This tells it to use the internal oscillator to get 16MHz
#define LED pin_B0
#INT_TIMER1
void timer1_isr(void)
{
output_toggle(LED);
set_timer1(65532); //Gives 4*8 counts
//clear_interrupt(INT_TIMER1); //Not needed unless you specify 'NOCLEAR'
//The compiler clears the interrupt for you
}
void main()
{
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_8);
set_timer1(65532);
//setup the timer before enabling it's interrupt
clear_interrupt(INT_TIMER1); // Clear Timer1 interrupt
enable_interrupts(INT_TIMER1); // Enable Timer1 interrupt
enable_interrupts(GLOBAL); // Enable global interrupts
while(1)
{}
}
|
You are not going to 'see' the LED toggle. At 500Hz (changing every mSec)
it'll just seem to be on, but dimmer than if directly driven.
With the slight extra delay involved in getting into the interrupt routine,
this should give just under 1mSec.
Generally, setting a timer 'to' a value, will never give accurate times. It
takes time to reach the instruction to do this, so clock counts will be
lost.
Look in the code library for a way of generating an accurate RTC. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sun Sep 01, 2019 4:51 am |
|
|
This...
http://www.ccsinfo.com/forum/viewtopic.php?t=26177
.. should be the correct link to the SW based RTC.
As for 'low power', you may find it easier to just add a larger capacity battery ! Cheap and easy. There are several 'tricks' to get very low power BUT you need to analyze the true overall power usage( millwatts / time ). There's 3 modes of operation 'run', 'crossover', 'sleep'.
Also all SW based RTC require the PIC to have a monitored power supply or 'fail safe' to battery opertion.
Currently my products use a RTC/EEPROM module. The DS32xx RTC is quite good,better than the DS1307. The EEPROM is used for some 'preset/default' data and the few bytes of battery backed RAM, I use for critical 'runtime' variables.
Jay |
|
|
rookiee
Joined: 31 Aug 2019 Posts: 5
|
|
Posted: Mon Sep 02, 2019 4:48 am |
|
|
Ttelmah wrote: | 65535, is the maximum count that the timer can hold. It's next count is
0 and the interrupt will occur. So just one count later the interrupt will occur.
Now, have you done a simple test to verify the chip is running?. I doubt if
it is. You are not telling it 'where' the 16Mhz is to come from. The default
oscillator setting assumes an external oscillator. So the chip won't run.
You can't actually generate a 1mSec 'tick' with a 32768Hz crystal. Think
about it 32.768 counts. However:
Code: |
#include <16F15376.h>
#device ADC=10
#use delay(INTERNAL=16MHz)
//This tells it to use the internal oscillator to get 16MHz
#define LED pin_B0
#INT_TIMER1
void timer1_isr(void)
{
output_toggle(LED);
set_timer1(65532); //Gives 4*8 counts
//clear_interrupt(INT_TIMER1); //Not needed unless you specify 'NOCLEAR'
//The compiler clears the interrupt for you
}
void main()
{
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_8);
set_timer1(65532);
//setup the timer before enabling it's interrupt
clear_interrupt(INT_TIMER1); // Clear Timer1 interrupt
enable_interrupts(INT_TIMER1); // Enable Timer1 interrupt
enable_interrupts(GLOBAL); // Enable global interrupts
while(1)
{}
}
|
You are not going to 'see' the LED toggle. At 500Hz (changing every mSec)
it'll just seem to be on, but dimmer than if directly driven.
With the slight extra delay involved in getting into the interrupt routine,
this should give just under 1mSec.
Generally, setting a timer 'to' a value, will never give accurate times. It
takes time to reach the instruction to do this, so clock counts will be
lost.
Look in the code library for a way of generating an accurate RTC. |
I had tried the exact same code, still the timer is not triggering, the LED did not turn on. The external crystal is connected with OSC1 and OSC2 with a parallel capacitor 22pF. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Mon Sep 02, 2019 5:12 am |
|
|
If you have an external crystal, then you need CRYSTAL=16MHz.
Before trying to use the interrupt, prove you have a working chip, running
at the clock speed expected:
Code: |
#include <16F15376.h>
#device ADC=10
#use delay(CRYSTAL=16MHz)
//This tells it to use an external crystal to get 16MHz
#define LED pin_B0
void main()
{
while(TRUE)
{
output_togglePIN_B0)
delay_ms(1000);
}
}
|
Get this working first.
Remember the LED must have a current limiting resistor.
Should give 1 second on. 1 second off. |
|
|
rookiee
Joined: 31 Aug 2019 Posts: 5
|
|
Posted: Mon Sep 02, 2019 9:55 pm |
|
|
Ttelmah wrote: | If you have an external crystal, then you need CRYSTAL=16MHz.
Before trying to use the interrupt, prove you have a working chip, running
at the clock speed expected:
Code: |
#include <16F15376.h>
#device ADC=10
#use delay(CRYSTAL=16MHz)
//This tells it to use an external crystal to get 16MHz
#define LED pin_B0
void main()
{
while(TRUE)
{
output_togglePIN_B0)
delay_ms(1000);
}
}
|
Get this working first.
Remember the LED must have a current limiting resistor.
Should give 1 second on. 1 second off. |
It give a around 16 second on and 16 second off. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 02, 2019 10:35 pm |
|
|
Post a list of the crystals that you have connected to your PIC, and
the pins that they are connected to. Post the frequency of each crystal.
Look on the crystal package with a magnifier, if necessary, to read the
crystal frequencies or markings. |
|
|
rookiee
Joined: 31 Aug 2019 Posts: 5
|
|
Posted: Mon Sep 02, 2019 10:57 pm |
|
|
PCM programmer wrote: | Post a list of the crystals that you have connected to your PIC, and
the pins that they are connected to. Post the frequency of each crystal.
Look on the crystal package with a magnifier, if necessary, to read the
crystal frequencies or markings. |
I am only using one external 32.768kHz crsystal and it is connected to OSC1 and OSC2 which is PA6 and PA7 with two parallel capacitor |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Mon Sep 02, 2019 11:46 pm |
|
|
OK.
You are misunderstanding how things have to be wired.
The OSC1 and OSC2 pins are for the _primary_ osciillator. This is the
crystal to run the actual chip. The master oscillator. If you want to use a
crystal to run the chip itself.
You can't run Timer1 off this. Now Timer1 on this chip is different
from most older PICs. To use an external crystal to feed this, it needs
to be connected to the secondary oscillator, and Timer1 has to be setup
to take it's clock from this. So T1_SOSC with pins RC0 and RC1.
Now it you only have the 32K crystal, then you need to be using
INTERNAL=16MHz as your master oscillator selection (since the crystal
will not be the 'master' oscillator). |
|
|
|