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

A/D Double Sleep Problem

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



Joined: 26 Feb 2014
Posts: 6

View user's profile Send private message

A/D Double Sleep Problem
PostPosted: Wed Feb 26, 2014 6:02 pm     Reply with quote

Hi everyone!

I'm trying to do an A/D conversion once a second, while keeping the PIC asleep for as long as possible. I want to sleep during the A/D conversion (a very short sleep, woken by the ADC interrupt), then execute another sleep (a longer 1 second sleep, woken by the watchdog timer).

I just cant get it to work! Run separately, I can get the sleep to work during the A/D conversion, and I can get the chip to sleep for 1 second so that the watchdog timer wakes it. But, when I put the two together it does not work. It looks like the A/D complete interrupt never fires and the WDT has to wake the chip. That means the A/D conversion takes a second to complete instead of a very short time.

I've been pouring over this for days and can't see why this is happening. Can anyone see anything I missed? I'm using PCH 5.008

Thanks

Code:

//***********CHIP CONFIG***********
#include <18F14K50.h>
#device PIC18F14K50
#device ADC=10
#fuses INTRC_IO,NOPROTECT,NOLVP,NOBROWNOUT,PUT,CPUDIV1,NOMCLR,NODEBUG //,WDT,WDT256
#use delay(clock=32M)

//*************MACROS*************
#define LED_Green(){output_high(PIN_C5);}
#define LED_Off(){output_low(PIN_C5);}

//************MAIN LOOP************
void main() {

    //Setup WatchDog Timer (for 1s wakeup from sleep)
    SETUP_WDT(WDT_1S|WDT_ON);

    //Setup the ADC
    setup_vref (VREF_2v048);
    setup_adc_ports(sAN4|sAN5|VSS_FVR);
    setup_adc(ADC_CLOCK_INTERNAL);
    set_adc_channel(4);
    delay_ms(1);
       
    //Disable Interrupts
    disable_interrupts(GLOBAL); //Don't need interrupts
   
    while(1){

        //Kick off ADC conversion and sleep
        enable_interrupts(INT_AD);          //We want the ADC to wake from sleep
        clear_interrupt(INT_AD);            //Clear ADC interrupt just in case
        restart_wdt();                      //Make sure WDT is reset
        LED_Green();                        //Turn on LED
        read_adc(ADC_START_ONLY);           //Trigger the ADC to start the process
        sleep();                            //Go to sleep and wait for ADC interrupt
        delay_cycles(1);                    //NOP

        //Woke up by ADC interrupt, so conversion is done.
        int16 valADC;
        valADC=read_adc(ADC_READ_ONLY);     //Get the ADC value

        //Disable ADC intterrupts
        disable_interrupts(INT_AD);         //No longer needed

        //Short delay then turn off LED
        restart_wdt();                      //Make sure chip doesn't reset
        delay_ms(50);                       //Delay 50ms so LED flashes
        LED_Off();                          //Turn LED Off
       
        //delay_ms(800);                    //Wait a while before next conversion
        sleep();                            //Sleep until next loop is due (WDT to wake PIC)
        delay_cycles(1);
    }
}
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Feb 26, 2014 6:19 pm     Reply with quote

have you tried 5.020?

i'd start there. Very Happy
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 26, 2014 7:12 pm     Reply with quote

There are parameters for sleep() given in the 18F14K50.h file:
Code:

// Constants for calls to sleep() are:
#define SLEEP_FULL       0  // Default
#define SLEEP_IDLE       1  // Clock and peripherals don't stop

Read the PIC data sheet and pick the one that works.
Maniac0Maniac2



Joined: 26 Feb 2014
Posts: 6

View user's profile Send private message

PostPosted: Thu Feb 27, 2014 4:42 pm     Reply with quote

PCM programmer -- spot on with that suggestion!

Sleep(SLEEP_IDLE) in the A/D section
Sleep(SLEEP_FULL) at the bottom

Works as expected - brought the power consumption right down! It's odd that Sleep(SLEEP_FULL) works for both separately, but not when I use them together.

Just blind curiosity, but it would be nice to know why this happens if someone out there has any insights!

My problem is solved thanks.
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Fri Feb 28, 2014 2:53 am     Reply with quote

You'd have to look at the assembler listing, but a 'guess', is that if you have just the ADC being used, and sleep,it doesn't clear the IDLEN bit, so gives sleep_idle. However when the watchdog is seen being used to wake it explicitly clears this bit. For either on it's own, this then works, but when both are being used, sleep_full will stop the ADC....
So when multiple sleeps are used, with one requiring the peripheral clock to stay running, you have to go 'explicit'.
Just a guess. Haven't got that particular compiler release.

As a comment, keep to the original C standard, and declare your variables either at the start of a function, or code segment. 'mid block' declaration, is a feature that was added to ANSI C, with C99. CCS allows it, but it has a 'habit' of causing some oddities, especially when used with more complex types, so better to stick to the older form. Stick to the C89 form for safety. It has gradually improved in CCS, and I haven't seen a problem for some months now, but I don't believe in 'looking for trouble'. There is no point in it in CCS (historically the idea is to reduce the scope of the variable, but as handled in CCS, the scope remains the same as when declared at the top of the code segment).

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