|
|
View previous topic :: View next topic |
Author |
Message |
oscillot Guest
|
waking up from read_adc() + sleep() |
Posted: Fri Dec 06, 2002 2:20 am |
|
|
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() |
Posted: Fri Dec 06, 2002 3:14 am |
|
|
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() |
Posted: Fri Dec 06, 2002 3:33 am |
|
|
:=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() |
Posted: Fri Dec 06, 2002 3:35 am |
|
|
:=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() |
Posted: Fri Dec 06, 2002 4:59 am |
|
|
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() |
Posted: Fri Dec 06, 2002 5:32 am |
|
|
:=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() |
Posted: Fri Dec 06, 2002 6:08 am |
|
|
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() |
Posted: Fri Dec 06, 2002 8:20 am |
|
|
:=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() |
Posted: Fri Dec 06, 2002 8:40 am |
|
|
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() |
Posted: Fri Dec 06, 2002 9:41 am |
|
|
:=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() |
Posted: Mon Dec 09, 2002 5:16 pm |
|
|
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() |
Posted: Tue Dec 10, 2002 9:20 am |
|
|
:=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 |
|
|
|
|
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
|