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

PIC18F47K42, Timer1 interrupt and sleep.

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



Joined: 27 Mar 2018
Posts: 25

View user's profile Send private message

PIC18F47K42, Timer1 interrupt and sleep.
PostPosted: Wed Oct 28, 2020 7:09 am     Reply with quote

While porting a code from PIC18LF47K40 to PIC18F47K42 that has the double of ram I found a problem that simplifying a lot is the following.

When I enable_interrupts(INT_TIMER1) regardless of disable_interrupts(GLOBAL) once the times fires for the first time the while(TRUE) loop starts looping without sleeping.

Same code with previous PIC18LF47K40 works fine.

I’ve disassembled the code and didn’t find nothing strange done by the compiler.

The fuses are in their the defaults.

Could someone help me?

Thank you in advance!

Code:

// PIC18F47K42, Timer1 interrupt and sleep...
// Migrating from PIC18LF47K40

#case

#include <18F47K42.h>

#use delay(clock = 16MHZ, internal)

#define LED       PIN_B5
#define PIN_TEST  PIN_C2

#INT_TIMER1
void timer1_isr()
{
   delay_cycles(1);
}

void main()
{
   output_low(LED); delay_ms(500); output_high(LED); delay_ms(500);
   
   setup_timer_1(T1_SOSC | T1_DIV_BY_8);   // External xtall 32768Hz
   
 //set_timer1(0x0000);   // After 16s PIN_TEST starts to toggle every 2us. 0x0000...0xffff at 32768/8 Hz => 16s.
   set_timer1(0x8000);   // After  8s PIN_TEST starts to toggle every 2us. 0x8000...0xffff at 32768/8 Hz =>  8s.
   
   enable_interrupts(INT_TIMER1);   // Without this line sleep works fine. <<<<<<<<<<<<<<<<<<<<<<<<<<<<
   disable_interrupts(GLOBAL);      // disable doesn't avoid it.
   
   while(TRUE)
   { 
      output_toggle(PIN_TEST);    // Toggles every 2us => sleep doesn't work.
      sleep();
      delay_cycles(1);
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19549

View user's profile Send private message

PostPosted: Wed Oct 28, 2020 8:25 am     Reply with quote

The problem is that the Timer1 interrupt gets set, and you have nothing to
clear it.
Timer1, is one of the peripherals that can wake the chip from sleep, so
once this triggers, it can't go to sleep.
Code:

   while(TRUE)
   {
      output_toggle(PIN_TEST);    // Toggles every 2us => sleep doesn't work.
      sleep();
      delay_cycles(1);
      clear_interrupts (INT_TIMER1);
   }

Adding the clear, allows the chip to go back to sleep if this interrupt
woke you. Without the clear the interrupt is permanently set once it triggers
so you can't then sleep.
In fact having an enable_interrupts(GLOBAL), would have allowed
the sleep to re-occur, with the interrupt handler then being called after
the wake up, and clearing the interrupt for you. Just with a slight extra
delay when this happens. Without the global enabled, the handler is never
called, so the interrupt is never cleared....
In either case though you will have an 'extra' wake up triggered by the
timer.
Josep Robert



Joined: 27 Mar 2018
Posts: 25

View user's profile Send private message

PostPosted: Fri Oct 30, 2020 5:13 am     Reply with quote

Thank you very much for your immediate help.

Now works fine.

Regards.

Code:

// PIC18F47K42, Timer1 interrupt and sleep...
// Migrating from PIC18LF47K40

#case

#include <18F47K42.h>   // 20/10/2020 1r 18F47K42 "sense L" provat.

#use delay(clock = 16MHZ, internal)

#define LED       PIN_B5
#define PIN_TEST  PIN_C2

#INT_TIMER1
void timer1_isr()
{
   set_timer1(0x8000);
   output_toggle(PIN_TEST);  // Toggle pin every 8 seconds.
   delay_cycles(1);
}

void main()
{
   output_low(LED); delay_ms(500); output_high(LED); delay_ms(500);
   
   setup_timer_1(T1_SOSC | T1_DIV_BY_8);   // External xtall 32768Hz
   
   set_timer1(0x8000);   // From 0x8000 to 0xffff at 32768/8 Hz => 8s.
   
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   
   output_high(PIN_TEST);
     
   while(TRUE)
   {
      sleep();
      delay_cycles(1);
   }
}
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