PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri May 20, 2011 5:14 pm |
|
|
Here's a demo program that I just wrote. It seems to work. A stopwatch
shows that it sleeps for 10 seconds. It wakes up once per second to check
the time. I tested this with a 16F1824 (that's in the same PIC family as
your PIC), and compiler version 4.121. I used a Microchip "low pin count"
board for the test, and added a 32.768 KHz crystal across pins 2 and 3,
with a 22 pf capacitor to ground, on each pin. I only tested it with delay
times of 1, 2, 3, 5, 10 seconds.
Code: |
#include <16F1824.H>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#define LED1 PIN_C1
#define LED2 PIN_C2
int8 sleep_timer = 0;
#define interrupt_enabled(x) !!(*make8(x,1) & make8(x,0))
//-------------------------------------------
#byte T1CON = getenv("SFR:T1CON")
#bit TMR1ON = T1CON.0
#byte TMR1H = getenv("SFR:TMR1H")
#byte TMR1L = getenv("SFR:TMR1L")
#define timer1_start() TMR1ON = 1;
#define timer1_stop() TMR1ON = 0;
// When Timer1 rolls over from 0xFFFF to 0x0000,
// this interrupt routine will be executed.
#int_timer1
void timer1_isr(void)
{
if(sleep_timer)
{
sleep_timer--;
timer1_stop();
bit_set(TMR1H, 7); // Set Timer1 MSB to 0x80
timer1_start();
}
}
//-------------------------------------------
// Sleep for the specified time of 1 to 255 seconds,
// Note: The PIC will actually wake-up once per second
// briefly, and check the remaining time.
void sleep_for_x_seconds(int8 seconds)
{
int8 global_interrupts_enabled;
sleep_timer = seconds; // Load sleep count into global variable
// Preset Timer1 so it will roll over in 1 second.
timer1_stop();
set_timer1(32768);
timer1_start();
if(interrupt_enabled(GLOBAL))
global_interrupts_enabled = TRUE;
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
// Wait in this loop until the desired delay in seconds is done.
while(sleep_timer)
{
sleep();
}
// We're done, so disable Timer1 interrupts.
disable_interrupts(INT_TIMER1);
// If global interrupts were disabled outside of
// of this routine, then disable them before we exit.
if(global_interrupts_enabled == FALSE)
disable_interrupts(GLOBAL);
}
//==========================================
void main()
{
// Start the Timer1 oscillator.
// Allow 5 seconds for it to start.
setup_timer_1(T1_EXTERNAL | T1_ENABLE_T1OSC | T1_DIV_BY_1);
delay_ms(5000);
output_high(LED1); // Turn on LED1 to show start of sleep.
sleep_for_x_seconds(10);
output_high(LED2); // Turn on LED 2 to show end of sleep.
while(1);
}
|
|
|