|
|
View previous topic :: View next topic |
Author |
Message |
armond Guest
|
ULPWU Feature |
Posted: Wed Jun 03, 2009 8:03 am |
|
|
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
|
|
|
armond Guest
|
ULPWU |
Posted: Wed Jun 03, 2009 12:17 pm |
|
|
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
|
|
Posted: Wed Jun 03, 2009 12:28 pm |
|
|
It's level triggered. If the input signal remains below the trigger voltage
threshold, the interrupt will be continuously generated. |
|
|
Guest
|
ULPWU |
Posted: Wed Jun 03, 2009 6:40 pm |
|
|
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. |
|
|
|
|
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
|