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

ULPWU Feature

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







ULPWU Feature
PostPosted: Wed Jun 03, 2009 8:03 am     Reply with quote

Hi,

I am using a PIC16F886 with ULPWU feature. I have a light sensor hooked up to PIN A0.
I want the pic to go to sleep when there is light on the sensor and wake up when the light goes away.
Then time out in the ISR and if no light go back to sleep waiting for the next Light to no light transition.
My question is? Does the ULPWU interrupt on both edges or just the H to L transition.
My code is working with the following anomalies. The processor wakes up when the light goes away, goes into the ISR
times out, but instead of going back to sleep, it goes back into the ISR and keeps repeating.
If during the ISR, the light goes on the sensor, it jumps out of the routine and goes back to sleep as it
should. It is only when allowed to timeout by itself, does it keep triggering the routine if the light is out.

Hope I made it as clear as possible,
Thanks in advance,
Code:

 #include "C:\Program Files\PICC\Projects\Led light\led_main.h"
 // #include <float.h>
 // #include <stdio.h>
 // #include <stdlib.h>
  #ZERO_RAM

//#use delay(clock=4000000,INTERNAL,RESTART_WDT)


byte read_int;
float  dummy;
byte lite_leds=False;
long minutes_to_run=1;
long sec_run=0;
long seconds_to_run;
byte no_run=0;
long multiple,first_timer,second_timer,third_timer,tick_counter;
float input_volts;
void full_power();
float get_voltage();
void two_thirds_power();
void one_third_power();
void read_switch();
long V6count;

void get_V6_count()
{
int cntr;
long sum=0;
int samples=100;



set_adc_channel (15);

delay_ms(5);


for(cntr=0;cntr<=samples;cntr++)
{
sum=read_adc()+sum;
delay_us(100);
}

input_volts= ((float)sum/(float)samples)* .00488;

v6count= .6*(1023/5);

}


void lite_the_leds()
{
 
//restart:          // jump after wakeup
                // start of sequence depend on flag



sec_run=0;
setup_timer_2(T2_DIV_BY_16,187,16);    // start and zero 1 sec timer
set_timer2(0);
read_switch();

seconds_to_run= minutes_to_run*60;     // calulate time to stay active
multiple= seconds_to_run/3;

first_timer= multiple;
second_timer=multiple*2;//
third_timer=multiple*3;
enable_interrupts(INT_TIMER2);         // 1 hz led flash routine
enable_interrupts(GLOBAL);



full_power();                       // turn on leds full power


do
{

delay_ms(5);
if(get_voltage()>.7)        // only on when its dark, reads sensor
                             // Get_Voltage  A/D  routine
{
goto all_over1;             // exit and shutdown
}
}while(sec_run<first_timer);  // 1st time interval
output_low(pin_B2);
delay_ms(10);                 // reset driver



two_thirds_power();           // 2/3 power


do
{

if(get_voltage()>.7)        // only  on when its dark
{
goto all_over1;
}
 delay_ms(5);
}while(sec_run<second_timer);

output_low(pin_B2);
delay_ms(10);

one_third_power();         // 1/3 power

do
{

delay_ms(5);
if(get_voltage()>.7)        // only turn on when its dark
{
goto all_over1;
}
}while(sec_run<third_timer);


all_over1:

lite_leds=false;           // clear flag

output_low(pin_B2);        // turn off leds
output_low(pin_C0);        // turn off 1 hz led
clear_interrupt(int_ULPWU);
disable_interrupts(INT_TIMER2);     // turn off seconds interuppenable_interrupts(INT_ULPWU);


}


Float get_voltage()
{
// this is universal routine to get the input voltage so we can decide whether to pwm or not
int cntr;
long sum=0;
int samples=100;

delay_ms(5);


for(cntr=0;cntr<=samples;cntr++)
{
sum=read_adc()+sum;
delay_us(100);
}


input_volts=((500*122)/(sum/samples));



input_volts= ((float)sum/(float)samples)* .00488;

return input_volts;
}


void one_third_power(void)
{
byte x=0;
byte y=0;

// address 2

output_high(pin_b2);    /// tsetup

for(y=0;y<=4;y++)
{

   
     output_low(pin_b2);
     delay_us(1);
     output_high(pin_b2);
     delay_us(1);
   
}

output_high(pin_b2);


}


void two_thirds_power(void)
{

byte x=0;
byte y=0;

// address 2

output_high(pin_b2);    /// tsetup

for(y=0;y<=9;y++)
{

   
     output_low(pin_b2);
     delay_us(1);
     output_high(pin_b2);
     delay_us(1);
}

output_high(pin_b2);

}



void full_power(void)

{

int   x;
// address 2
output_high(pin_b2);    /// tsetup
delay_us(2);

for(x=0;x<=14;x++)
{
output_low(pin_b2);
delay_us(5);
output_high(pin_b2);
delay_us(5);
}

output_high(pin_b2);      // reset data
}


void read_switch(void)        // read switch to get time on
{

 byte msb3,msb2,msb1,lsb;

set_tris_c(0b11110000);

output_high(pin_c2);
delay_ms(10);                         // set pin hi to energize

msb3 = input(pin_c7)*8;
msb2 = input(pin_c6)*4;
msb1 = input(pin_c5)*2;
lsb = input(pin_c4)*1;

minutes_to_run=msb3+msb2+msb1+lsb;
output_low(pin_c2);
//minutes_to_run=3;
set_tris_c(0b11111111);


}


//    ###############################            this is what starts the light on sequence
#INT_ULPWU
void ULPW_isr(void)
{
//######################## in order to get here the room light must be off

lite_the_leds();



}

//#################################################################################


//######################################   pyro detector

#int_EXT            // this is pyro interrupt
void  EXT_isr(void)
{

//          not used now

return;
if(get_voltage()>.2)        // only turn on when its dark

{
return;
}

lite_leds=true;
sec_run=0;


}




//###########################Seconds timer
#int_TIMER2
void  TIMER2_isr(void)
{
tick_counter++;
if (tick_counter>20)
{
sec_run++;
output_toggle(pin_c0);
tick_counter=0;
}

}


void main()
{
   
   set_tris_A(0b11111111);
   setup_oscillator(OSC_4MHZ);
   setup_adc_ports(sAN1|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(SPI_SS_DISABLED);
   set_adc_channel (1);
   
   //enable_interrupts(INT_EXT);            // pyro interrupt
   //EXT_INT_EDGE(L_TO_H);
   setup_timer_2(T2_DIV_BY_16,187,16);

   // 
   //
      output_low(pin_C1);
      output_High(pin_A7); ///    led ground
do
{      //      pyro test     

PIE2=0B00000100;        // only works when these  are set
                        // setup ULPWU Interrupt
PCON=0B00100000;

//enable_interrupts(int_ulpwu);
//clear_interrupt(int_ULPWU);
enable_interrupts(global);
  sleep();


Delay_cycles(1);        // NOP




lite_the_leds();
// jump to here calls the ULPWU ISR



}while(1);
//goto all_over;

 
 }
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 03, 2009 11:45 am     Reply with quote

Quote:

Does the ULPWU interrupt on both edges or just the H to L transition?

In AN879, on page 2, it says:
Quote:
The interrupt is level triggered

So, it's not edge-triggered.
Link to AN879:
http://ww1.microchip.com/downloads/en/AppNotes/00879D.pdf

Wikipedia article on edge-triggered and level-triggered interrupts:
http://en.wikipedia.org/wiki/Interrupt
armond
Guest







ULPWU
PostPosted: Wed Jun 03, 2009 12:17 pm     Reply with quote

Now my question is, what happens if the line stays low. Will the PIC continue to service it? or wait for the next H to lo again.. It seems to keep servicing the ISR.

Thanks,
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 03, 2009 12:28 pm     Reply with quote

It's level triggered. If the input signal remains below the trigger voltage
threshold, the interrupt will be continuously generated.
Guest








ULPWU
PostPosted: Wed Jun 03, 2009 6:40 pm     Reply with quote

Now we're getting somewhere, that's what I thought was happening. I just expected it to fire the interrupt once and then not trigger another till the pin went high again. Next question, anyway around it? Or do I have to change the wiring and use the comparators?

Thanks again.
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