View previous topic :: View next topic |
Author |
Message |
aries
Joined: 17 Jun 2011 Posts: 2 Location: United States
|
Sleep and timer1 |
Posted: Fri Jun 17, 2011 10:40 am |
|
|
I am using Timer1 to wake up from sleep mode but it does not wake up at all. Here is the code:
Code: |
#include <16F74.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES LP //Low power osc < 200 khz
#FUSES NOBROWNOUT //Reset when brownout detected
#FUSES NOPROTECT //Program memory not write protected
//#FUSES NOPUT //No Power Up Timer
#FUSES PUT //Power Up Timer
#use delay(clock=65535)
#case
#byte TMR1L=0x0E
#byte TMR1H=0x0F
#byte T1CON=0x10
#define TMR1ON T1CON=0x0C
#define TMR1OFF T1CON=0x0D
// LCD display definitions
#define LCD_ENABLE_PIN PIN_A3
#define LCD_RS_PIN PIN_B7
#define LCD_RW_PIN PIN_B6
#define LCD_DATA4 PIN_C4
#define LCD_DATA5 PIN_C5
#define LCD_DATA6 PIN_C6
#define LCD_DATA7 PIN_C7
#define LCD_TYPE 2
#include <lcd.c>
// Global variables
unsigned int8 IsSecond=0; // one second flag
unsigned string[]=" ";
// Functions definitions
void lcd_putstring(unsigned int8 *string);
void main()
{
lcd_init();
lcd_gotoxy(1,1);
strcpy(string,"POWER UP ");
lcd_putstring(string);
delay_ms(1000);
lcd_gotoxy(1,1);
strcpy(string,"SLEEPING ");
lcd_putstring(string);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
sleep();
delay_ms(1000);
lcd_gotoxy(1,1);
strcpy(string,"BACK IN MAIN");
lcd_putstring(string);
while(1);
}
void lcd_putstring(unsigned int8 *string)
{
while(*string)
{
lcd_putc(*string);
string++;
}
}
#INT_TIMER1
void Timer1_handler(void)
{
disable_interrupts(INT_TIMER1);
lcd_gotoxy(1,1);
strcpy(string,"WOKE UP NOW ");
lcd_putstring(string);
IsSecond = TRUE;
}
|
Timer1 is setup for 4 seconds and I know it is working, by commenting out the line sleep(), the LCD displays as expected. With the sleep() active, timer1 does not seem to generate interrupt, LCD is stuck at "SLEEPING".
Could someone tell me what I did wrong and what would it take to make it work?
TJ |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 17, 2011 12:37 pm |
|
|
Quote: | #include <16F74.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES LP //Low power osc < 200 khz
#FUSES NOBROWNOUT //Reset when brownout detected
#FUSES NOPROTECT //Program memory not write protected
//#FUSES NOPUT //No Power Up Timer
#FUSES PUT //Power Up Timer
#use delay(clock=65535)
|
I assume this means you have a 65.535 KHz crystal (and capacitors)
connected to the OSC1 and OSC2 pins on the PIC. Is that true ?
Here you have configured Timer1 to run from the internal PIC oscillator:
Quote: |
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
|
But the main oscillator is turned off during sleep mode. Timer1 won't
run during sleep. From the 16F74 data sheet:
Quote: |
12.14 Power-down Mode (SLEEP)
Power-down mode is entered by executing a SLEEP
instruction.
If enabled, the Watchdog Timer will be cleared but
keeps running, the PD bit (STATUS<3>) is cleared, the
TO (STATUS<4>) bit is set, and the oscillator driver is
turned off.
|
Also, the 16F74 data sheet says to wake up from sleep, Timer1 must run
from an external clock (in other words, a clock source outside the PIC):
Quote: |
12.14.1 WAKE-UP FROM SLEEP
The following peripheral interrupts can wake the device
from SLEEP:
2. TMR1 interrupt. Timer1 must be operating as
an asynchronous counter. |
Here are some posts about using Timer1 with the Timer1 oscillator, with
a watch crystal on the T1OSC pins. These are different pins than the
main oscillator pins:
http://www.ccsinfo.com/forum/viewtopic.php?t=28158&start=8
http://www.ccsinfo.com/forum/viewtopic.php?t=45458&start=5 |
|
|
aries
Joined: 17 Jun 2011 Posts: 2 Location: United States
|
|
Posted: Fri Jun 17, 2011 1:26 pm |
|
|
Thanks for the response.
I misunderstood the datasheet. I was assuming that there is an internal clock for Timer1 and asynchronous refers to async to system clock.
I can use the WDT to do this instead. What I am trying to do is to stay in sleep mode and periodically wakes up to do a task and go back to sleep.
How would I intercept the WDT interrupt coming out of sleep mode so it does not go reset?
TJ |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 17, 2011 2:10 pm |
|
|
There is no WDT interrupt. |
|
|
rsegecin
Joined: 23 Aug 2011 Posts: 12
|
|
Posted: Fri Aug 26, 2011 1:59 pm |
|
|
aries wrote: | Thanks for the response.
I misunderstood the datasheet. I was assuming that there is an internal clock for Timer1 and asynchronous refers to async to system clock.
I can use the WDT to do this instead. What I am trying to do is to stay in sleep mode and periodically wakes up to do a task and go back to sleep.
How would I intercept the WDT interrupt coming out of sleep mode so it does not go reset?
TJ |
Hi Aries. I'm new at CCS programming but I think that I know what you are trying to say here, do you mean that you would like to distinguish whether the pic got reseted from the sleep or not? As far that I know you could do something like that:
Code: |
switch(restart_cause())
{
case WDT_FROM_SLEEP:
BlinkLedAndSleep();
break;
case WDT_TIMEOUT:
break;
case MCLR_FROM_SLEEP:
break;
case MCLR_FROM_RUN:
break;
case NORMAL_POWER_UP:
BlinkLedAndSleep();
break;
case BROWNOUT_RESTART:
break;
default:
output_high(PIN_A1);
delay_ms(1000);
output_low(PIN_A1);
break;
}
|
You can find those values "WDT_FROM_SLEEP, BROWNOUT_RESTART, ...." in the pic's header file. If you make it work please let me know, cause I'm stuck trying to make the WDT to work.
Best regards. |
|
|
|