View previous topic :: View next topic |
Author |
Message |
asturkinos
Joined: 16 Nov 2003 Posts: 5 Location: Asturias-Spain
|
attend to TIMER2 interrupt while serving another interrupt?? |
Posted: Fri Jan 02, 2004 3:44 am |
|
|
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
|
Re: attend to TIMER2 interrupt while serving another interru |
Posted: Fri Jan 02, 2004 10:52 am |
|
|
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
|
Interrupts and more |
Posted: Fri Jan 02, 2004 3:23 pm |
|
|
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
|
|
Posted: Sat Jan 03, 2004 12:28 pm |
|
|
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
|
thnx |
Posted: Sat Jan 03, 2004 3:15 pm |
|
|
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
|
interrupt an interrupt |
Posted: Mon Jan 05, 2004 3:40 pm |
|
|
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
|
bootloader! |
Posted: Mon Jan 05, 2004 4:19 pm |
|
|
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----------------------------
---------------------------------------------------------- |
|
|
|