![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
ch_dupre
Joined: 22 Aug 2006 Posts: 18
|
waking up from sleep using timer1. |
Posted: Tue Sep 04, 2007 4:08 am |
|
|
Hello,
I am trying to put the PIC to sleep and wake it up using TIMER1. I've been using the WDT timer in the past but I'd like to have a better accuracy using TIMER1.
I'm using a PIC18LF2620
CCS v4.033 and also V3.249
I can observe 2 things:
1: If the timer value is 0xFB00 or more, I can't see the PIC going to sleep, and the message: "Wakeup on T1\n" from the isr isn't printed on the serial port. On the other hand, the while loop keeps going.
2: if the Timer value is less than 0xFB00, the PIC goes to sleep but never wakes up.
Here is my code:
Main.c
Code: |
#include "main.h"
#BYTE T1CON = 0xFCD
#BIT T1SYNC=T1CON.2
void main()
{
while ( 1 )
{
fprintf( COM2, "Go to Sleep\n" );
set_timer1(0xF000);
//setup_timer_1(T1_EXTERNAL_SYNC| T1_DIV_BY_8);
T1CON= 0xBF; //16bit, div8, osc en, ext clk, TMRON
enable_interrupts(INT_TIMER1);
sleep();
delay_ms( 500 );
}
}
#INT_TIMER1
void timer1_isr()
{
disable_interrupts( INT_TIMER1 );
setup_timer_1( T1_DISABLED );
delay_ms( 4000 );
fprintf( COM2, "Wakeup on T1\n" );
} |
main.h
Code: |
#ifndef _MAIN_H
#define _MAIN_H
#include <18F2620.h>
#device adc=8
#IF getenv("VERSION")>4.001
#device ANSI
#ENDIF
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT8192 //Watch Dog Timer uses 1:8192 Postscale: for about 30s sleeping time
#FUSES HS //High speed Osc (> 4mhz)
//#FUSES INTRC
#FUSES NOPROTECT //Code not protected from reading
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV21 //Brownout reset at 2.1V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES DEBUG //No Debug mode for ICD
#FUSES NOLVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#use delay(clock=20000000)
//#use rs232(baud=9600, parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//#ifdef __DEBUG__
#use rs232(baud=57600, parity=N,xmit=PIN_B0,/*rcv=PIN_A5,*/bits=8, invert, STREAM=COM2)
//#endif
#endif //_MAIN_H
|
Thanks for your help.
Christophe D. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Tue Sep 04, 2007 5:17 am |
|
|
Comment one.
The interrupt code, will _only_ get executed, if both the interrupt is enabled, and the global interrupt flag is set. Without the global flag, the interrupt will only wake the chip. 3.5.1 in the data sheet.
Second, if the interrupt handler is not called, it becomes _your_ responsibility to clear the interrupt flag. You need to do this before sleeping, or the code will never wake. You should do this anyway, otherwise if the flag is set, the CPU will not go to sleep.
In the 'setup_timer' version, you want:
setup_timer_1(T1_DIV_BY_8 | T1_EXTERNAL | T1_CLK_OUT);
Given external input, output, to form the oscillator, and the division by eight.
Get rid of the IESO fuse. This will imply, that because the T1 oscillator is running, you will almost certainly _not_ see messages printed just after wake up. With this set, the chip will wake up immediately from sleep, without waiting for the main oscillator to start. It'll run the first few dozen instructions, at the speed that T1 is running, not the master clock. This means that any serial print done here, wll just result in garbage. Lok at 23.3.1 in the data sheet. The delay in the interrupt, will probably avoid this, but it is a danger.
Get rid of the delay in the interrupt routine. Since delays are used in both the interrupt code, and also the main, this will result in interrupts automatically being disabled in the main, wherever delays are used. On sleep, the instruction immediately after the sleep, is 'prefetched', and in some cases, may actually be partially performed, before the sleep is entered. This could really screw things up...
[code]
#INT_TIMER1
void timer1_isr(void) {
fprintf( COM2, "Wakeup on T1\n" );
}
void main()
{
//setup timer just once
setup_timer_1(T1_DIV_BY_8 | T1_EXTERNAL | T1_CLK_OUT);
while ( 1 )
{
//ensure any print from the interrupt has completed
delay_ms(30);
fprintf( COM2, "Sending to Sleep\n" );
set_timer1(0xF000);
clear_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
sleep();
//ensure the prefetched instruction is nop
delay_cycles(1);
delay_ms( 500 );
}
}
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
ch_dupre
Joined: 22 Aug 2006 Posts: 18
|
|
Posted: Tue Sep 04, 2007 8:33 am |
|
|
Thanks Tthelmah.
I've modified my code to :
Code: |
#INT_TIMER1
void timer1_isr(void)
{
fprintf( COM2, "T1 ON\n" );
setup_timer_1( T1_DISABLED );
}
void main()
{
delay_ms( 1000 );
fprintf( COM2, "Program Start\n" );
while ( 1 )
{
delay_ms(30);
fprintf( COM2, "Sendingi to Sleep\n" );
set_timer1(0xF600); //the PIC will not wake up if this values is < 0xF600
setup_timer_1(T1_DIV_BY_8 | T1_EXTERNAL | T1_CLK_OUT);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
sleep();
//ensure the prefetched instruction is nop
delay_cycles(1);
delay_ms( 500 );
}
}
|
That works quite well for small duration. Unfortunately, it doesn't work if the timer value is less than oxF600.
That looks like a hardware bug to me. I've checked the errata but I can't see anything obvious there.
Thanks,
Christophe D. |
|
![](templates/subSilver/images/spacer.gif) |
kevcon
Joined: 21 Feb 2007 Posts: 142 Location: Michigan, USA
|
|
![](templates/subSilver/images/spacer.gif) |
ch_dupre
Joined: 22 Aug 2006 Posts: 18
|
|
Posted: Tue Sep 04, 2007 10:56 am |
|
|
I'm using a 20MHz crystal, and a 32,768KHz oscillator connected on RC0.
Christophe D. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|