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

Awake from sleep with ADC interrupt

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



Joined: 07 Feb 2011
Posts: 26

View user's profile Send private message

Awake from sleep with ADC interrupt
PostPosted: Wed Feb 23, 2011 11:21 pm     Reply with quote

I want to awake the mcu from sleep mode using the adc interrupt and the portb change. I got the portb change work fine, but I could not get the adc interrupt part to awake the processor from sleep.

Is there a special way to do this?

I use the mechatronic demo board with 16f917 processor.

here are my files:

main.c

Code:
include <mechatronic.h>
#include "interrupt.c"

//----------------------------------------------
//Main program start here
void main()
{

   
   
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   read_adc(ADC_START_ONLY);
   port_b_pullups(0xF0);        // Enable pull-ups on pins B4-B7
   temp = input_b();         // current value on portb
   
   clear_interrupt(INT_RB);   // ensure interrupt is clear before enable interrupt
    enable_interrupts(INT_AD);
   enable_interrupts(INT_RB4);   // enable intertupt b on change b4
   enable_interrupts(GLOBAL);   // enable global interrupt
   
   while(1)
   {
      if(!input(SW4))      //if sw4 press, go to sleep
      {
         printf("\r\n");
         printf("Processor is SLEEP\n\r");
         sleep();
      }
      else      // else MCU alive.
      {
         output_high(LED2);
         delay_ms(100);
         output_low(LED2);
         delay_ms(100);
         printf("\r\n");
         printf("Processor is A LIVE\n\r");
      }
   }
}




interrupt.c


Code:


//Global variables
int8 x;
int8 temp;
int1 done;
unsigned char   adc_result;
//----------------------------------------------
// Interrupt Service Routine
#INT_RB
void interrupt_ISR()
{
      x = input_b();            // copy PORTB to x
      output_toggle(LED1);      // turn led on d7
      delay_ms(10);
      clear_interrupt(INT_RB);   // clear interrupt   
      
}

#INT_AD
void ADC_ISR()
{
   
   adc_result = read_adc();
   clear_interrupt(INT_AD);
}



mechatronic.h file


Code:
/*
File name mechatronic.h, it is an include file
*/

#include <16F917.H>
#device ICD=TRUE  ADC=10
#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)



#define SW3   PIN_B4
#define SW4   PIN_A5


#define   LED1   PIN_D7

#define LED2   PIN_D6

#define FALSE   0
#define   TRUE   1

FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Feb 24, 2011 12:37 am     Reply with quote

Except for the initial read_adc(ADC_START_ONLY), there's no statement, that would start an ADC conversion.
read_adc() is waiting for the conversion to complete and doesn't cause a new interrupt.
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Thu Feb 24, 2011 3:58 am     Reply with quote

Code:

//Main program start here
void main()
{
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   port_b_pullups(0xF0);        // Enable pull-ups on pins B4-B7
   temp = input_b();         // current value on portb
   
   clear_interrupt(INT_RB);   // ensure interrupt is clear before enable interrupt
   enable_interrupts(INT_RB4);   // enable interrupt b on change b4
   enable_interrupts(GLOBAL);   // enable global interrupt
   
   while(1)
   {
      if(!input(SW4))      //if sw4 press, go to sleep
      {
         printf("\r\n");
         printf("Processor is SLEEP\n\r");
         //To wake using the ADC, you don't need an ADC int handler, and
         //don't want other interrupts enabled.
         disable_interrupts(GLOBAL); //prevent handlers being called
         disable_interrupt(INT_RB4);
         enable_interrupt(INT_AD);
         clear_interrupt(INT_AD);
         //Now start the ADC conversion
         read_ADC(ADC_START_ONLY);
         //and immediately sleep - you have _one_ instruction time to do this
         sleep();
         //Instruction after the sleep is 'prefetched' - should be a NOP
         delay_cycles(1);
         //When you wake, the ADC has completed the conversion
         adc_result=read_adc(ADC_READ_ONLY);
         disable_interrupt(INT_AD);
         enable_interrupt(INT_RB4);
         enable_interrupt(GLOBAL);
      }
      else      // else MCU alive.
      {
         output_high(LED2);
         delay_ms(100);
         output_low(LED2);
         delay_ms(100);
         printf("\r\n");
         printf("Processor is A LIVE\n\r");
      }
   }
}


The ADC interrupt triggers 12 cycles of the ADC clock after the conversion is started.

I don't think it'll actually do what you want. The only way to get the ADC interrupt to trigger, is to start a conversion. Nothing will happen from the ADC interrupt while you are asleep otherwise...
You don't want other interrupts enabled while performing a 'sleep' ADC conversion. The whole 'point' of it, is to have the processor 'halted' to get rid of the noise sources. If other interrupts are enabled, they will potentially introduce noise.

You can trigger a ADC conversion using the CCP module, provided this is clocked from an external clock, and this could then wake the chip.

You can though on chips with the comparator, wake on a _comparator_ interrupt, when a voltage goes beyond a specified level. This might be more in line with what you want?.

Best Wishes
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