View previous topic :: View next topic |
Author |
Message |
lokinhas
Joined: 11 Feb 2009 Posts: 6
|
PIC16F616 timer 1 wake up from sleep |
Posted: Wed Feb 11, 2009 3:48 pm |
|
|
Hi there!
I´m using a PIC16F616 that is always in sleep mode, and will wake up every time 1 second pass. It works with the internal 32kHz clock, and uses timer1 to generate an interrupt. The problem is that when it goes to sleep it never wakes up.
I have tried without the sleep instruction and the program works. This is the code i have done.
Code: | #include <16F616.h>
#fuses LP
#fuses INTRC_IO
#fuses NOWDT
#fuses NOPROTECT
#fuses PUT //Delay de 64ms
#fuses MCLR
#fuses BROWNOUT //Reset quando VDD=2,15V
#fuses BROWNOUT_NOSL //Brownout enabled during operation, disabled during SLEEP
#use delay(internal=32000)
unsigned int16 aux=0;
#INT_TIMER1
void timer1_sri(void){
aux++;
clear_interrupt(INT_TIMER1);
enable_interrupts(GLOBAL);
set_timer1(0);
output_low(PIN_C2);
}
void main(){
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
do{
output_toggle(PIN_C2);
sleep();
}while(TRUE);
} |
Can someone help? Need help urgent. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 11, 2009 4:10 pm |
|
|
Quote: |
#fuses LP
#fuses INTRC_IO
|
You're attempting to use two different Oscillator settings.
Here's what the 16F616 data sheet says:
Quote: | LP – 32 kHz Low-Power Crystal mode. (External crystal)
INTOSCIO – Internal oscillator with I/O on OSC1/CLKIN and OSC2/CLKOUT. |
If you want the internal oscillator, don't specify "LP" mode.
Use INTRC_IO.
Quote: | #fuses BROWNOUT //Reset quando VDD=2,15V
#fuses BROWNOUT_NOSL //Brownout enabled during |
Again, don't specify two modes of the same feature. They are not
additive. Specify only one of them.
Quote: | #INT_TIMER1
void timer1_sri(void){
aux++;
clear_interrupt(INT_TIMER1);
enable_interrupts(GLOBAL);
set_timer1(0);
output_low(PIN_C2);
} | Don't enable global interrupts inside an interrupt service routine.
Nested interrupts are not supported for the PCM compiler.
Also, you don't need to clear the interrupt inside the routine.
The compiler inserts (hidden) code at the end of the routine to clear
the Timer1 interrupt flag.
Quote: | do{
output_toggle(PIN_C2);
sleep();
}while(TRUE); |
Read the 16F616 data sheet. It explains that you can wake up the
PIC with the Timer1 interrupt, but the timer must be running from
an external clock (not the internal oscillator or even an external
watch crystal on the main oscillator pins).
Quote: | 12.7.1 WAKE-UP FROM SLEEP
The following peripheral interrupts can wake the device
from Sleep:
1. Timer1 interrupt. Timer1 must be operating as an asynchronous counter. |
16F616 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/41288D.pdf
You can put an external watch crystal on the Timer1 oscillator pins
(with appropriate capacitors), and configure Timer1 to run from the
Timer1 oscillator. Then it will still run even though the PIC is in sleep
mode. After Timer1 counts up to 0xFFFF and overflows, it will generate
an interrupt and the PIC will wake up. See this sample program:
http://www.ccsinfo.com/forum/viewtopic.php?t=28158&start=8
The PIC can still run from it's internal oscillator. But wake-up from
sleep will be controlled by Timer1 which runs from an external watch
crystal (32.768 KHz). |
|
|
lokinhas
Joined: 11 Feb 2009 Posts: 6
|
|
Posted: Wed Feb 11, 2009 5:06 pm |
|
|
Sorry, but i posted the wrong code, this is the code i'm using.
Code: | #include <16F616.h>
#fuses LP
#fuses WDT
#fuses NOPROTECT
#fuses PUT //Delay de 64ms
#fuses MCLR
#fuses BROWNOUT //Reset quando VDD=2,15V
#fuses BROWNOUT_NOSL //Brownout enabled during operation, disabled during SLEEP
#use delay(clock=32768,oscillator)
unsigned int16 aux=0;
#INT_TIMER1
void timer1_sri(void){
disable_interrupts(INT_TIMER1);
aux++;
clear_interrupt(INT_TIMER1); //clear à interrupção
output_low(PIN_C2);
enable_interrupts(INT_TIMER1);
}
void main(){
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
do{
output_toggle(PIN_C2);
sleep();
}while(TRUE);
} |
I'm using a external 32,768kHz crystal with 2 22pF capacitors.
Thanks for the reply, but didn't resolved the problem... |
|
|
lokinhas
Joined: 11 Feb 2009 Posts: 6
|
|
Posted: Wed Feb 11, 2009 5:08 pm |
|
|
Forgot to tell that i'm using an external clock, and not a the internal clock as said in the 1st post. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 11, 2009 5:10 pm |
|
|
When the PIC is in sleep mode, the main oscillator does not run.
Your code configures Timer1 to run from the main oscillator.
Therefore, Timer1 does not run when the PIC is sleeping.
The PIC will not wake-up with your code.
If you want the PIC to wake-up from Timer1 interrupt, add another
watch crystal and capcitors to the Timer1 oscillator. Look at the
sample code that I posted. |
|
|
lokinhas
Joined: 11 Feb 2009 Posts: 6
|
|
Posted: Wed Feb 11, 2009 5:15 pm |
|
|
Ok. Then can i use the internal oscillator to run the PIC and the external crystal for the timer1? Any idea of the capacitors i should use for the external clock?
Thanks for the help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 11, 2009 5:21 pm |
|
|
The PicDem2-Plus board uses 22 pf capacitors with the 32.768 MHz
watch crystal, when it's connected to the Timer1 oscillator pins.
(T1OSO and T1OSI pins). |
|
|
lokinhas
Joined: 11 Feb 2009 Posts: 6
|
|
Posted: Wed Feb 11, 2009 5:32 pm |
|
|
Thanks for all the help! Problem finally resolved! |
|
|
|