CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

PIC16F636 won't wake up

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
johnl



Joined: 30 Sep 2003
Posts: 120

View user's profile Send private message

PIC16F636 won't wake up
PostPosted: Mon Feb 20, 2012 10:26 am     Reply with quote

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: 8528
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Feb 20, 2012 12:13 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Feb 20, 2012 12:30 pm     Reply with quote

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: 21667

View user's profile Send private message

PostPosted: Mon Feb 20, 2012 1:50 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Feb 20, 2012 1:53 pm     Reply with quote

YES!! Thank you.
Ttelmah



Joined: 11 Mar 2010
Posts: 18124

View user's profile Send private message

PostPosted: Mon Feb 20, 2012 3:45 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Feb 21, 2012 8:27 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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