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

If statement in isr
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

If statement in isr
PostPosted: Tue Dec 24, 2019 4:46 pm     Reply with quote

Dear all,

I made a small code that every 1 second an ISR is executed and in this ISR there is an if...then...else statement. But i am noticing that after about 12 minutes, the isr is not executing every 1 second but every 1.4 seconds. I think that the if statement is too long to be handled in ISR. Is there a better way to use if statement and keep the isr as short as possible?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 24, 2019 8:00 pm     Reply with quote

Post your
1. Timer setup code in main().
2. Isr routine.
3. PIC oscillator setup code (#fuses and #use delay() )
Also post if a crystal or the internal oscillator is used.
4. Post your PIC.
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 5:21 am     Reply with quote

Along with PCM Ps comments...

ISRs must be short and quick so

NO floating point math
NO printing
NO 'complex' math
NO delays of any kind

Try to use only 8 bit unsigned variables

You should set 'flags' inside ISRs and let main() do what's needed.


as PCMP says..post your code
Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 8:54 am     Reply with quote

The O.P. has not posted his code, so I will post a link to what I suspect
the problem might be:
Accuracy problem in timer0 interrupt -
http://www.ccsinfo.com/forum/viewtopic.php?t=49716
Read the replies by ckielstra and Ttelmah.
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 12:01 pm     Reply with quote

Dear All,

Sorry I had some problems with my mail..now everything is ok. Well the code is:

Code:
#include <mainrtc.h>

int count_s;

#INT_RTCC
void  RTCC_isr(void)
{
   count_s++;
   if (count_s == 60)
   {
      output_toggle(PIN_B4);
     
   }
   else
   output_toggle(PIN_B3);

}

void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);      //1.0 s overflow
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   setup_low_volt_detect(FALSE);

   while(TRUE)
   {
     
   }

}


I made the code simple for you to explain. I made the Timer0 to overflow every 1s but after about some seconds, it starts to increase...instead of 11s..12s..13.. it is 11.05...12.07 etc

I am using PIC18F248 and crystal of 4MHz.
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 12:38 pm     Reply with quote

I also read the post "Accuracy problem in timer0 interrupt" and i know that inside ISR there is code that take time to be executed. I am just asking if there is another way I can work to reduce this time.
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 12:55 pm     Reply with quote

Two items I see
1) you don't select 8bit or 16 bit mode for the timer
2) you don't preset the counter

I'll assume the mode is 8 bit.. the 'default' but you should check that.
The lower byte of the timer0 counter is anything on powerup, so at lest for the first interrupt it could be almost any time, after that it should always be 256*16 microseconds, I think. But that's only 4,096 us NOT 1 second.
4MHz clk/4=1 us to timer.....

I'm waiting for turkey so maybe I'm not thinking right !?

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 1:06 pm     Reply with quote

temtronic, I compiled it and it defaults to 16 bit.

aaronik19,
Your code doesn't give a 1 second interrupt period.
It gives an interrupt period of 1.048576 seconds.

The math:

Instruction clock divided by prescaler:
1 MHz / 16 = 62500 Hz clock for Timer0.

Timer0 clock / size of 16-bit Timer0:
62500 / 65536 = 0.9536743 Hz interrupt rate

Convert rate to period:
1 / 0.9536743 Hz = 1.048576 seconds per interrupt.
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 1:42 pm     Reply with quote

hmm... according to the datasheet, it 'should' be 8 bit mode, so I assume CCS defaults to 16 bit mode...
Thanks for checking !
beginning to smell like turkey here, can't get much done......
'tis the season' 1
Cheers
Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 2:25 pm     Reply with quote

Here is the compiled code, below. It's putting 0x83 into T0CON.
That value makes bit 6 = 0, which gives a 16-bit counter.
This is from the data sheet:
Quote:

bit 6 T08BIT: Timer0 8-bit/16-bit Control bit
1 = Timer0 is configured as an 8-bit timer/counter
0 = Timer0 is configured as a 16-bit timer/counter


See the value in bold below:
Quote:

.................... void main()
00C6: CLRF TBLPTRU
00C8: BCF RCON.IPEN
00CA: BSF 07.7
00CC: BSF ADCON1.PCFG0
00CE: BSF ADCON1.PCFG1
00D0: BSF ADCON1.PCFG2
00D2: BCF ADCON1.PCFG3
.................... {
.................... setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16); //1.0 s overflow
00D4: MOVLW 83
00D6: MOVWF T0CON
.................... enable_interrupts(INT_RTCC);
00D8: BSF INTCON.T0IE
.................... enable_interrupts(GLOBAL);
00DA: MOVLW C0
00DC: IORWF INTCON,F
.................... setup_low_volt_detect(FALSE);
00DE: CLRF LVDCON
....................
.................... while(TRUE)
.................... {
00E0: BRA 00E0
....................
.................... }
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 2:54 pm     Reply with quote

Dear all...infact it is 16 bit. I set it from the wizard.
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 3:14 pm     Reply with quote

I must be getting old and fussy....
..OK, turkey's not done yet either....so...

Curious, I opened up the CCS manual....
and in the setup_timer_0(mode).... information

"PIC18XXX only: RTCC_OFF, RTCC_8_BIT"

Even though uChip defaults the PIC to 8 bit mode, CCS defaults to 16 bit mode !!

I'd have expected an 'RTCC_16_BIT' option as it's NOT the factory default.
The only way you'd really know is to dump the listing....

Oh well, learned something today..

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 25, 2019 7:19 pm     Reply with quote

Try this method. See if it works better.
Code:

#include <18F46K22.h>
#fuses XT, NOWDT, BROWNOUT, PUT, NOPLLEN
#use delay(clock=4M)

#define T0_PRELOAD  (65536 - 62500)  // Count for 62500 T0 clocks
int count_s = 0;

// Timer0 is in 16-bit mode.  It interrupts once per second.
#INT_TIMER0
void TIMER0_isr(void)
{
set_timer0(T0_PRELOAD + get_timer0()); // Adjust for interrupt overhead

count_s++;

if(count_s == 60)
  {
   output_toggle(PIN_B4);
   count_s = 0;    // Need to reset count_s if it reaches 60
  }
else
  output_toggle(PIN_B3);

}

//======================================

void main(void)
{
setup_timer_0(T0_INTERNAL | RTCC_DIV_16);   // T0 clock = 62.5 KHz
set_timer0(T0_PRELOAD);
enable_interrupts(INT_TIMER0);
clear_interrupt(INT_TIMER0);
enable_interrupts(GLOBAL);

while(TRUE);
}
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Dec 27, 2019 1:18 pm     Reply with quote

Thre's also this....
http://www.ccsinfo.com/forum/viewtopic.php?t=26177

a SW RTC that I've used on several PICs over the years, though I prefer a HW RTC giving the PIC an interrupt every second. HW RTC also has battery backup, usually some CMOS RAM as well.

just another option to consider.

Jay
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Sun Dec 29, 2019 2:04 am     Reply with quote

Dear All,

I continue to read about timers on PIC Micro and on the PIC18F248 there is an option to make external crystal for timer 1 T1OSI and T1OSO. So I think that if I can connect 32.768kHz crystal and 33pF to ground I might get a perfect 1 second interrupt.

the code that I tried from PCM worked good...thanks
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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