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 CCS Technical Support

Timer1() and Sleep() Code Basics

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



Joined: 23 Jun 2004
Posts: 24

View user's profile Send private message

Timer1() and Sleep() Code Basics
PostPosted: Wed Sep 22, 2004 12:36 pm     Reply with quote

Hi,

I just wanted to get some basics to get me started in the right direction.

This is what I want to do:
I need to be able to place a PIC18F4320 to sleep and only turn on the PIC at a certain interval (this can vary from once every 1sec to once every 24hrs---depending on customer request).

I will be implementing an external clock 32.728Khz for use in sleep mode.

I want to implement the Timer1 interrupt right before the sleep function and, of course, wakeup after the correct time interval and then sleep until the next interval.

Just for testing, I want to blink an LED for the set time interval.
I'm not quite sure how to 'fire' on Timer1() and exactly what code needs to go into TIMER1_isr() .


This is some basic code that I have:


Code:


#int_TIMER1
TIMER1_isr()
{

code

}

void main(){

   int x;
   
   
   
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT); // 1:1 Prescalar Value
   TMR1ON = 0; //turn off timer1
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   set_timer1(0);
   



      for (x=0;x<=2;++x){

         output_high(POWER_LED);   //test OK indicator//
         #ifdef NormalCode
         delay_ms(500);
         #endif
         output_low(POWER_LED);
         #ifdef NormalCode
         delay_ms(500);
         #endif
         }

      
   TMR1ON = 1;//turn on timer1

   sleep();

   TMR1ON = 0;///turn off timer1

      for (x=0;x<=2;++x)

         output_high(LINK_LED);   //test up OK indicator//
         #ifdef NormalCode   
         delay_ms(500);
         #endif
         output_low(LINK_LED);
         #ifdef NormalCode
         delay_ms(500);
         #endif




}


Any help will be appreciated. Thanks.
ninjanick



Joined: 25 May 2004
Posts: 25

View user's profile Send private message

PostPosted: Wed Sep 22, 2004 11:52 pm     Reply with quote

Not really sure if TIMER1 is active during SLEEP. Might want to check the datasheet. But as a suggestion, you could do exactly what you want with the WDT.
jpage



Joined: 23 Jun 2004
Posts: 24

View user's profile Send private message

Timer1() and Sleep() Code Basics
PostPosted: Thu Sep 23, 2004 8:46 am     Reply with quote

Thanks. I'll check out the datasheet.

I just thought that since I was using an external XTAL (32.728Khz) on Timer1, it would continue running (counting) while the main processor clock (4MHZ) turned off.

I would use the WDT, but this is a battery operated device that we are trying to minimize current and it looked like this (Timer1) would be the best method. I think the WDT uses the internal clock and will draw more current than if the uP was completely asleep.

This is basically what I want to do:

Run the Main() program
Sleep()
Enable the Timer1() ISR
After Timer1() timeout --return or resume to Main()
Start whole process over again using forever loop --While(1)

Note: Would like the uP to Sleep anywhere from 1sec to 24hrs

Will the above sequence work??
When Timer1() timeouts and exits ISR, will this automatically wake up the processor??

Thanks for any help.
jpage



Joined: 23 Jun 2004
Posts: 24

View user's profile Send private message

Timer1() and Sleep() Code Basics
PostPosted: Thu Sep 23, 2004 12:05 pm     Reply with quote

Just wanted to get a reality check on the code below.

I want to blink an LED 2 times and then put the uP in sleep mode.
Sleep mode will shut down the internal XTAL and start the External
XTAL (32.728Khz). Timer1() will start counting up to 65,536 (2 seconds) and then rollover to 0 which will trigger an interrupt and wake the uP.


Can anyone give me any feedback on this??
Thanks.



Code:


#include <18f4320.H>
#fuses HS,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
#use delay (clock=4000000)



#define POWER_LED      PIN_E0

#define NormalCode




#int_TIMER1
void timer1_isr()
{
   set_timer1(0);
}

void main()
{

   int x;
   
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT); // 1:1 Prescalar Value   

   
   enable_interrupts(GLOBAL);
   
while(1){   

      for (x=0;x<=2;++x)
         {

         output_high(POWER_LED);   //test OK indicator//
         #ifdef NormalCode
         delay_ms(500);
         #endif
         output_low(POWER_LED);
         #ifdef NormalCode
         delay_ms(500);
         #endif
         }

      enable_interrupts(INT_TIMER1);

      sleep();
      
      }
   
   


   

return;

}

ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Sep 23, 2004 4:30 pm     Reply with quote

Basically I think your code should work, but there is some room for optimizations.

1) Your #fuses line
Code:
#fuses HS,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP

You can save a little more power by disabling the internal RC-oscillator, for this both the watchdog and the Fail-Safe Clock Monitor must be disabled.
- Add NOWDT to disable the watchdog.
- Add NOFCMEN to disable the Fail-Safe Clock Monitor.

2) Sorry, your interrupt routine makes no sense.
The interrupt is called on the rollover to 0, so why set Timer1 to 0 again? You can remove this line and leave your interrupt funtion empty. The only reason for having your interrupt function would then be to clear your interrupt (the compiler takes care of this for you).

A further improvement is to remove the interrupt routine at all. Check Chapter 28.4 of the PIC18C Reference Manual, here is explained that the PIC will awake from sleep when the interrupt enable bit for timer1 is set. But, by not setting the Global Interrupt Enable bit, the PIC will not execute an interrupt and continue directly with the instruction after the sleep().

3) Just a design note: I don't know what your circuit looks like, but be aware that floating inputs can generate a considerable current consumption caused by noise causing high frequent switching from low to high state. This bit me once. After reset most I/O ports are configured as inputs, just make sure all (unused) inputs are connected to Vdd or Vss.

4) Do not return from main().
At the end of your main() function you have a return statement, this doesn't belong there. The main function never has a return statement because nobody ever called it. In some other compilers you would place a call to exit() here to exit your program but in CCS you don't. CCS will automatically add a sleep() to the end of your program.

5) Your LED will blink 3 times, not 2 times.
Code:
    for (x=0;x<=2;++x)

Change the '<=' to '<'.

All changes added to your code:
Code:
#include <18f4320.H>
#fuses HS,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP, NOWDT, NOFCMEN  // Added NOWDT and NOFCMEN
#use delay (clock=4000000)

#define POWER_LED      PIN_E0
#define NormalCode


// Removed interrupt function
//#int_TIMER1
//void timer1_isr()
//{
//   set_timer1(0);
//}

void main()
{
   int x;
   
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT); // 1:1 Prescalar Value   

   
   // enable_interrupts(GLOBAL);  // Not required
   enable_interrupts(INT_TIMER1);  // Moved out of loop
   
  while(1)
  {
    for (x=0;x<2;++x)  // Changed '<=' to '<'
    {
      output_high(POWER_LED);   //test OK indicator//
      #ifdef NormalCode
        delay_ms(500);
      #endif
      output_low(POWER_LED);
      #ifdef NormalCode
        delay_ms(500);
      #endif
    }
    // enable_interrupts(INT_TIMER1);  // Moved out of loop
    sleep();
    clear_interrupt(INT_TIMER1);     // added
  }
  // return;   // Removed
}
[/quote]
jpage



Joined: 23 Jun 2004
Posts: 24

View user's profile Send private message

Timer1() and Sleep() Code Basics
PostPosted: Thu Sep 23, 2004 8:39 pm     Reply with quote

Thanks very much for your comments, ideas, and suggestions.

It was very helpful.

I appreciate the heads up on floating pins and tieing them high or low.


With the code right now, the uP will blink the LED and then sleep for 2 seconds, wakeup, and repeat forever.

If I want to lengthen the sleep time to a preset value, do I just increment a counter and keep track of the counter in the main() with a while loop??

Something like this:

Code:



int counter = 0;


#int_TIMER1
void timer1_isr()
{
   counter++

 }

void main()
{
.
.
.
while (counter < 2){// loops 3 times to keep in sleep mode for 6 sec.
 enable_interrupts(INT_TIMER1);  // Moved out of loop
    sleep();
    clear_interrupt(INT_TIMER1);     // added

}

)





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