View previous topic :: View next topic |
Author |
Message |
johnl
Joined: 30 Sep 2003 Posts: 120
|
PIC16F636 won't wake up |
Posted: Mon Feb 20, 2012 10:26 am |
|
|
Trying to get this to power up in sleep mode and wake up to flash an LED when a button push makes A0 go low.
Eventually I need to distinguish a short button press from a long one but for now just trying to get the wake up routine to work.
The compiler is 3.218 and yes I know it's old. That's why I'm trying not to rely too much on the library interrupt functions.
Code: |
#include <16F636.h>
#fuses INTRC_IO,NOPROTECT,NOCPD,MCLR,NOIESO,NOWDT,NOPUT, NOFCMEN,WURE,NOBROWNOUT
#use fast_io(A)
#use delay(clock=8000000)
#byte WPUDA=0x95
#byte WDA=0x97
#byte OPTION_REG=0x81
#byte INTCON = 0x8B
#byte IOCA = 0x96
static short go_to_sleep = TRUE;
short dummy;
#INT_RA
void ioc_isr()
{
go_to_sleep = FALSE;
INTCON = 0; //turn off all ints
delay_ms(100);
}
void init(void);
void main()
{
init();
if (go_to_sleep)
{
dummy = input(PIN_A0);
INTCON = 0b10001000; //GIE, RAIE enabled
IOCA = 1; // AO int on change enabled
sleep();
delay_cycles(1);
}
while(1) //flash LED
{
output_toggle(PIN_C0);
delay_ms(100);
}
}
void init(void)
{
set_tris_a(1);
set_tris_c(0);
setup_comparator(NC_NC_NC_NC);
setup_oscillator(OSC_8MHZ);
OPTION_REG = 0b01111111; //enable pullups
output_high(PIN_C0); //turn off LED
WPUDA = 1; ///select Pullup
WDA = 1; /// ...on A0
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Mon Feb 20, 2012 12:13 pm |
|
|
hint:
You've decided to use fast_io().....please read the manual(F11 if project open) on the FULL implications of what _you_ have to do when using ...fast_io(). |
|
|
johnl
Joined: 30 Sep 2003 Posts: 120
|
|
Posted: Mon Feb 20, 2012 12:30 pm |
|
|
The manual says I am responsible for the direction register when using fast_io. Setting the directions up is the very first thing done in init(). What am I missing?
Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 20, 2012 1:50 pm |
|
|
Quote: | #fuses INTRC_IO,NOPROTECT,NOCPD,MCLR,NOIESO,NOWDT,NOPUT, NOFCMEN,WURE,NOBROWNOUT
|
You have the #fuses configured to reset the PIC upon wake-up. |
|
|
johnl
Joined: 30 Sep 2003 Posts: 120
|
|
Posted: Mon Feb 20, 2012 1:53 pm |
|
|
YES!! Thank you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Mon Feb 20, 2012 3:45 pm |
|
|
You do realise, that you _don't_ need the global interrupt enabled, or an interrupt handler present to wake up on interrupts?.
The compiler functions do seem to work OK with your version.
I just simplified the code to:
Code: |
#include <16F636.h>
#FUSES NOWDT, INTRC_IO, NOPROTECT, NOCPD, NOMCLR, NOIESO, NOPUT, NOFCMEN, NOWURE, NOBROWNOUT
#use delay(clock=8000000)
void main() {
int8 dummy;
int8 nctr;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_low_volt_detect(FALSE);
for (nctr=1;nctr<10;nctr++) {
output_toggle(PIN_C0);
delay_us(10);
}
//Burst of five pulses on C0 to show we are awake and starting
do {
dummy=input_a();
clear_interrupt(INT_RA);
enable_interrupts(INT_RA0);
sleep();
delay_cycles(1);
//Now turn the interrupt off
disable_interrupts(INT_RA);
for (nctr=1;nctr<10;nctr++) {
output_toggle(PIN_C1);
delay_us(10);
}
//Burst of pulses on C1 to show we have woken
} while (TRUE);
}
|
and it merrily wakes when A0 changes.
A lot simpler.....
Best Wishes |
|
|
johnl
Joined: 30 Sep 2003 Posts: 120
|
|
Posted: Tue Feb 21, 2012 8:27 am |
|
|
Ttelmah,
Very interesting and elegant code.
I see from your example that the instruction after sleep() is where execution continues upon waking. I assumed execution resumes at the beginning of main(). Hence the variable 'go_to_sleep' to direct program flow, which I now see is not needed.
Also I thought every interrupt must have a handler..not true!
Couple of questions: Why do you set up timer0 and disable timer1? Also why deal with low voltage detect and vref?
Thank you! Your wake-on-change example is the best and clearest one I've seen.
John |
|
|
|