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

attend to TIMER2 interrupt while serving another interrupt??

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



Joined: 16 Nov 2003
Posts: 5
Location: Asturias-Spain

View user's profile Send private message Send e-mail MSN Messenger

attend to TIMER2 interrupt while serving another interrupt??
PostPosted: Fri Jan 02, 2004 3:44 am     Reply with quote

Hi All:

I'm woking in a little code whit two interrupts:

-TIMER2, this make a write to the I2C bus every 125us aprox.

-CANRX0, when 8 bytes of data have been received in the CAN RX0 buffer this saves them to a RAM buffer.

Well, it works right but I have been reading the forum and I think that using two interrupts can cause troubles in real time using... Now the cuestions:

Imagine that the PIC is attending to the CAN bus interrupt (CANRX0), What's about the other interrupt flag is set? I think TIMER2 interrupt will delay, is that right?

Do you know any trick to avoid this? I mean: I need the TIMER2 interrupt to be attened exactly every 125 us...Is this posible when using another interupts?

A little code can clarify:
Code:

#int_CANRX0
void irs_CANRX0()
{
   can_getd(rx_id,&buffer[CAN_ptr],rx_len,rxstat);
    buffer_cnt=buffer_cnt+8;
    CAN_ptr=CAN_ptr+8;
    if(CAN_ptr > (TAMANO_BUFFER-1)){CAN_ptr=0;}

}

#int_TIMER2
void isr_DAC()
{
   set_timer2(vel_I2C);
   disable_interrupts(INT_CANRX0);
   i2c_write(buffer[I2C_ptr]);
   enable_interrupts(INT_CANRX0);
   I2C_ptr++;
   buffer_cnt--;
   if(I2C_ptr > (TAMANO_BUFFER-1)){I2C_ptr=0;}

}
void main()
....
......


I tink the lines "disable_interrupts(INT_CANRX0);" and "enable_interrupts(INT_CANRX0);" are redundant....

I'm actually using PIC18F248 and PIC18F448

Tanks to all!!! and happy new year!
_________________
----------------------------------------------------------------------------------kinOs----------------------------
----------------------------------------------------------
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: attend to TIMER2 interrupt while serving another interru
PostPosted: Fri Jan 02, 2004 10:52 am     Reply with quote

asturkinos wrote:
Hi All:

I'm woking in a little code whit two interrupts:

-TIMER2, this make a write to the I2C bus every 125us aprox.

-CANRX0, when 8 bytes of data have been received in the CAN RX0 buffer this saves them to a RAM buffer.

Well, it works right but I have been reading the forum and I think that using two interrupts can cause troubles in real time using... Now the cuestions:

Imagine that the PIC is attending to the CAN bus interrupt (CANRX0), What's about the other interrupt flag is set? I think TIMER2 interrupt will delay, is that right?

Do you know any trick to avoid this? I mean: I need the TIMER2 interrupt to be attened exactly every 125 us...Is this posible when using another interupts?

A little code can clarify:
Code:

#int_CANRX0
void irs_CANRX0()
{
   can_getd(rx_id,&buffer[CAN_ptr],rx_len,rxstat);
    buffer_cnt=buffer_cnt+8;
    CAN_ptr=CAN_ptr+8;
    if(CAN_ptr > (TAMANO_BUFFER-1)){CAN_ptr=0;}

}

#int_TIMER2
void isr_DAC()
{
   set_timer2(vel_I2C);
   disable_interrupts(INT_CANRX0);
   i2c_write(buffer[I2C_ptr]);
   enable_interrupts(INT_CANRX0);
   I2C_ptr++;
   buffer_cnt--;
   if(I2C_ptr > (TAMANO_BUFFER-1)){I2C_ptr=0;}

}
void main()
....
......


I tink the lines "disable_interrupts(INT_CANRX0);" and "enable_interrupts(INT_CANRX0);" are redundant....

I'm actually using PIC18F248 and PIC18F448

Tanks to all!!! and happy new year!


You might experience some "jitter". For example if you were to toggle a pin as the first thing you do in the timer 2 interupt and then watch it on a scope, you would see an extremly consistant average time but there would be some edges that occur too late followed by another that occures too soon. The timers are free running and the interupt flags are set when they overflow. If two interupt flags occure at the same time one will be serviced and then the other one. If it takes 50uS to service your CAN port, and the timer interupt occures right after service of the CAN port begins the timer interupt will be at least 50uS late. On the up side service of each occurancs of each interupt is independent so there is no accumulation of delays unless there is more demand for service of interupts than time to service interupts.
asturkinos



Joined: 16 Nov 2003
Posts: 5
Location: Asturias-Spain

View user's profile Send private message Send e-mail MSN Messenger

Interrupts and more
PostPosted: Fri Jan 02, 2004 3:23 pm     Reply with quote

Thanks a lot Neutone!

I think there is no way to achieve more accuracy.... PIC is PIC and no more :-), a lot of good and a bit of lacks....

Well, now I'm tryn' this:

Code:

....
int1 CANRX0_flag

#int_CANRX0
void irs_CANRX0()
{
     CANRX0_flag=1
}

#int_TIMER2
void isr_DAC()
{
  set_timer2(vel_I2C);
  disable_interrupts(INT_CANRX0);
  i2c_write(buffer[I2C_ptr]);
  enable_interrupts(INT_CANRX0);
  I2C_ptr++;
  buffer_cnt--;
  if(I2C_ptr > (TAMANO_BUFFER-1)){I2C_ptr=0;}

}
void main()
....
......
if(CANRX0_flag)
{
  CANRX0_flag=0;
  can_getd(rx_id,&buffer[CAN_ptr],rx_len,rxstat);
  buffer_cnt=buffer_cnt+8;
  CAN_ptr=CAN_ptr+8;
  if(CAN_ptr > (TAMANO_BUFFER-1)){CAN_ptr=0;

}
....
//NOTE: TAMANO_BUFFER=Buffer length (spanish TAMAŅO=length xD)


I think this could be a good way to handle CANRX0 interrupt... but I have not been able to try today...

Thanks to all!
_________________
----------------------------------------------------------------------------------kinOs----------------------------
----------------------------------------------------------
drolleman
Guest







PostPosted: Sat Jan 03, 2004 12:28 pm     Reply with quote

to handle more than one interupt you must do...

1) on interupt find out who did the interupt
2) disable the interupt that caused it
3) in your servicing of the interupt wait until the flag is down
4) reenable the interupt that you are servicing.

there is only one interupt so if there is two interupts at the same time only the first one will be serviced untill the flag is down
asturkinos



Joined: 16 Nov 2003
Posts: 5
Location: Asturias-Spain

View user's profile Send private message Send e-mail MSN Messenger

thnx
PostPosted: Sat Jan 03, 2004 3:15 pm     Reply with quote

Thanks drolleman, the next monday I'll try all of your ideas and anotherone more of mine...
_________________
----------------------------------------------------------------------------------kinOs----------------------------
----------------------------------------------------------
Keegan



Joined: 10 Sep 2003
Posts: 1
Location: Columbus, OH

View user's profile Send private message Visit poster's website

interrupt an interrupt
PostPosted: Mon Jan 05, 2004 3:40 pm     Reply with quote

asturkinos,

On the PIC18 devices you can use interrupt priority (low and high) by adding 'FAST' to the interupt directive.

ex:
Code:

#int_CANRX0
void can_isr()
{
   //code
}

#int_TIMER2 FAST
void timer2_isr()
{
   //code
}


This may be a simple fix, look at IPR3:0 (address 0xFA5 bit 0) to see if it is clear (this is the priority bit for CANRX0).

-Keegan
asturkinos



Joined: 16 Nov 2003
Posts: 5
Location: Asturias-Spain

View user's profile Send private message Send e-mail MSN Messenger

bootloader!
PostPosted: Mon Jan 05, 2004 4:19 pm     Reply with quote

Thanks for your replay Keegan, I did not try the PIC18 interrupt priority cos in my proyect I'm using a bootloader.... A part of my boot code is:


Code:

//Bootloader pruebas 28 pines
#Build (RESET=0x200)            
#Build (INTERRUPT=0x208)         
#ORG 0x000,0x1FF {}            
  void bootloader(){#asm nop #endasm}
#ORG default



I think there is no way to use priorities whit this bootloader... I'm looking for this here but I DON'T KNOW if it's posible to do something similar to:

Code:

#Build(INTERRUPT_HIGH=0x218)        //Maybe wrong!!!!!
#Build(INTERRUPT_LOW=0x208)         //Maybe wrong!!!!!


However I'll try the interrupt priority disablig the bootloader.... maybe tomorrow.... ;-)

Thanks a lot!
_________________
----------------------------------------------------------------------------------kinOs----------------------------
----------------------------------------------------------
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