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

waking up from read_adc() + sleep()

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







waking up from read_adc() + sleep()
PostPosted: Fri Dec 06, 2002 2:20 am     Reply with quote

Hey guys,

It says in the data sheet that you can lessen digital noise in the PIC16F877 when utilizing the A/D converter by using the internal A/D clock, enabling int_adc, and using a sleep() command immediately after your read_adc() command...
But perhaps I am misunderstanding something? I tried doing exactly that, and I can't get my program to wake back up, which it is automatically supposed to do I thought? Through test lights, I am pretty sure I get as far as the end of the AD interrupt, but unfortunatley nothing happens after that. Anyone here have any experience with this? Here's what I'm trying to do:


#int_ad
ad_isr(){
disable_interrupts(INT_ADC);
}

void main() {
setup_adc_ports(A_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_counters(RTCC_INTERNAL,RTCC_DIV_16);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
enable_interrupts(global);

set_adc_channel(0);

while(true){
enable_interrupts(INT_ADC);
foo=read_adc();
sleep();
}
}


(in .h file)
#include <16F877.h>
#device ICD=TRUE
#use delay(clock=38400)
#fuses LP,NOWDT
#use rs232(baud=1200,parity=N,xmit=PIN_C6,rcv=PIN_C7)



Naturally, any and all feedback will be much appreciated. Thanks!
___________________________
This message was ported from CCS's old forum
Original Post ID: 9815
oscillot
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Fri Dec 06, 2002 3:14 am     Reply with quote

hmm, weird. somehow i got it to work. probably because i'm not disabling/reenabling the adc interrupt anymore.
___________________________
This message was ported from CCS's old forum
Original Post ID: 9816
R.J.Hamlett
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Fri Dec 06, 2002 3:33 am     Reply with quote

:=Hey guys,
:=
:=It says in the data sheet that you can lessen digital noise in the PIC16F877 when utilizing the A/D converter by using the internal A/D clock, enabling int_adc, and using a sleep() command immediately after your read_adc() command...
:=But perhaps I am misunderstanding something? I tried doing exactly that, and I can't get my program to wake back up, which it is automatically supposed to do I thought? Through test lights, I am pretty sure I get as far as the end of the AD interrupt, but unfortunatley nothing happens after that. Anyone here have any experience with this? Here's what I'm trying to do:
:=
:=
:=#int_ad
:=ad_isr(){
:= disable_interrupts(INT_ADC);
:=}
:=
:=void main() {
:= setup_adc_ports(A_ANALOG);
:= setup_adc(ADC_CLOCK_INTERNAL);
:= setup_spi(FALSE);
:= setup_psp(PSP_DISABLED);
:= setup_counters(RTCC_INTERNAL,RTCC_DIV_16);
:= setup_timer_1(T1_DISABLED);
:= setup_timer_2(T2_DISABLED,0,1);
:= setup_ccp1(CCP_OFF);
:= setup_ccp2(CCP_OFF);
:= enable_interrupts(global);
:=
:= set_adc_channel(0);
:=
:= while(true){
:= enable_interrupts(INT_ADC);
:= foo=read_adc();
:= sleep();
:= }
:=}
:=
:=
:=(in .h file)
:=#include <16F877.h>
:=#device ICD=TRUE
:=#use delay(clock=38400)
:=#fuses LP,NOWDT
:=#use rs232(baud=1200,parity=N,xmit=PIN_C6,rcv=PIN_C7)
:=
:=
:=
:=Naturally, any and all feedback will be much appreciated. Thanks!

There are two problems here. The first is that the 'read_adc' function, has allready completed the ADC read, before it exits. The second is that the ADC interrupt source has to be enabled to do the wake up, _but_ the global interrupt should normally be disabled. If you look at the 'logic' for the interrupts, all the individual sources are gated by their individual enable bits, and this line then feeds the 'wake up' signal, and goes to the final output gate, where if GIE is set, an actual interrupt will occur. This is not wanted, or the result will be a call to an interrupt handler.
To use the sleep ability, you should enable the ADC interrupt, and disable the global interrupt. Then in your code, define:
#bit ADGO=0x1f.2
#bit ADON=0x1f.0
#bit ADIF=0xC.6
#byte ADRESL=0x9E
#byte ADRESH=0x1E

//Then for your sample.

set_adc_channel(0);
ADON=true;
//Add a slight delay here, or on the first loop, the input
//capacitor will not be fully charged following source
//selection.
delay_us(15);
while(true){
disable_interrupts(GLOBAL);
enable_interrupts(INT_ADC);
//Ensure the interrupt flag is clear.
ADIF=false;
//Start the conversion.
ADGO=true;
sleep();
disable_interrupts(INT_ADC);
enable_interrupts(GLOBAL)
//Note that these only need to be enabled at all
//if you are intending to use another interrupt.
foo=make16(ADRESH,ADRESL);
}
}

You do not need an ISR for the AD interrupt (since none should occur, with the global interrupt disabled). Also unless you are using another interrupt source, you can just leave the global interrupt bit permanently disabled (this is not used by the 'wake up' logic).

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 9817
R.J.Hamlett
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Fri Dec 06, 2002 3:35 am     Reply with quote

:=hmm, weird. somehow i got it to work. probably because i'm not disabling/reenabling the adc interrupt anymore.

What will happen in this case, is that the ADC bit will be set, by the read_adc function, and you will fall through the sleep. Your reading will have allready been taken with the chip awake, and you won't get the improved readings you are after...

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 9818
oscillot
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Fri Dec 06, 2002 4:59 am     Reply with quote

RJ, thanks so much. you are the man.
___________________________
This message was ported from CCS's old forum
Original Post ID: 9823
R.J.Hamlett
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Fri Dec 06, 2002 5:32 am     Reply with quote

:=RJ, thanks so much. you are the man.
Thanks.

Good luck with your project
___________________________
This message was ported from CCS's old forum
Original Post ID: 9824
oscillot
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Fri Dec 06, 2002 6:08 am     Reply with quote

shoot, you know what, now it won't wake up from sleep though. i know this because when i comment it out, my program doesn't hang anymore.
this is stressing me...
___________________________
This message was ported from CCS's old forum
Original Post ID: 9825
R.J.Hamlett
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Fri Dec 06, 2002 8:20 am     Reply with quote

:=shoot, you know what, now it won't wake up from sleep though. i know this because when i comment it out, my program doesn't hang anymore.
:=this is stressing me...
Post the actual code section now. I have used this in the past, and it worked fine, but I could easily have missed something....

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 9831
oscillot
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Fri Dec 06, 2002 8:40 am     Reply with quote

RJ, i want you to know that i really appreciate this. even if you can't find anything.


(from the .h)
#include <16F877.h>
#device ICD=TRUE
#use delay(clock=38400)
#fuses LP,NOWDT
#use rs232(baud=1200,parity=N,xmit=PIN_C6,rcv=PIN_C7)


(from the .c)
#int_tbe
tbe_isr(){
// transmit bytes
index++;
putchar(msg[index]);
// if last byte transmitted, stop transmission
if(index==4){
disable_interrupts(INT_TBE);
}
}


void main() {
set_rtcc(0);
setup_adc_ports(A_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_counters(RTCC_INTERNAL,RTCC_DIV_16);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);

set_adc_channel(0);
ADON=true;
delay_us(15);

while(true){

disable_interrupts(GLOBAL);
disable_interrupts(INT_RTCC);
disable_interrupts(INT_TBE);
enable_interrupts(INT_ADC);
output_bit(PIN_E0, 1);
output_bit(PIN_E1, 0);
ADIF=0;
ADGO=1;
sleep();
disable_interrupts(INT_ADC);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_TBE);
enable_interrupts(GLOBAL) ;

msg[4]=ADRESH;
msg[3]=ADRESL;
index=3;
putchar(msg[3]);
}
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 9833
R.J.Hamlett
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Fri Dec 06, 2002 9:41 am     Reply with quote

:=RJ, i want you to know that i really appreciate this. even if you can't find anything.
:=
:=
:=(from the .h)
:=#include <16F877.h>
:=#device ICD=TRUE
:=#use delay(clock=38400)
:=#fuses LP,NOWDT
:=#use rs232(baud=1200,parity=N,xmit=PIN_C6,rcv=PIN_C7)
:=
:=
:=(from the .c)
:=#int_tbe
:=tbe_isr(){
:= // transmit bytes
:= index++;
:= putchar(msg[index]);
:= // if last byte transmitted, stop transmission
:= if(index==4){
:= disable_interrupts(INT_TBE);
:= }
:=}
:=
:=
:=void main() {
:= set_rtcc(0);
:= setup_adc_ports(A_ANALOG);
:= setup_adc(ADC_CLOCK_INTERNAL);
:= setup_spi(FALSE);
:= setup_psp(PSP_DISABLED);
:= setup_counters(RTCC_INTERNAL,RTCC_DIV_16);
:= setup_timer_1(T1_DISABLED);
:= setup_timer_2(T2_DISABLED,0,1);
:= setup_ccp1(CCP_OFF);
:= setup_ccp2(CCP_OFF);
:=
:=set_adc_channel(0);
:=ADON=true;
:=delay_us(15);
:=
:=while(true){
:=
:= disable_interrupts(GLOBAL);
:= disable_interrupts(INT_RTCC);
:= disable_interrupts(INT_TBE);
:= enable_interrupts(INT_ADC);
:= output_bit(PIN_E0, 1);
:= output_bit(PIN_E1, 0);
:= ADIF=0;
:= ADGO=1;
:= sleep();
:= disable_interrupts(INT_ADC);
:= enable_interrupts(INT_RTCC);
:= enable_interrupts(INT_TBE);
:= enable_interrupts(GLOBAL) ;
:=
:= msg[4]=ADRESH;
:= msg[3]=ADRESL;
:= index=3;
:= putchar(msg[3]);
:= }
:=}
A simple fault!.
The problem is that the bit 'PEIE', has to be enabled for wake-up to work. Whether this is set or not with the code as given depends on the compiler version (the current versions disable this at the same time as the GIE bit), but if you add:
#bit PEIE=0xB.6

And then after enabling the INT_AD, and the global disable, add the line:
PEIE=1;

It should then work.
Note also it should refer to INT_AD, not INT_ADC in the code.

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 9834
oscillot
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Mon Dec 09, 2002 5:16 pm     Reply with quote

eureka! it works!
___________________________
This message was ported from CCS's old forum
Original Post ID: 9915
R.J.Hamlett
Guest







Re: waking up from read_adc() + sleep()
PostPosted: Tue Dec 10, 2002 9:20 am     Reply with quote

:=eureka! it works!
The annoying thing is that that particular problem (the clearing of PEIE by the disable interrupt function), caught me when it first appeared on the CCS compiler (earlier versions only cleared GIE), and I had forgotten it!...
Glad it is sorted now,

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 9935
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