|
|
View previous topic :: View next topic |
Author |
Message |
keup00 Guest
|
bug with interrupt during while loop (PCM 3.19) |
Posted: Sun Jul 18, 2004 5:28 am |
|
|
When I have an interrupt during the last instruction of a while loop, PCL do not return at the beginning of the while (even with a true condition), but instead it exits the while and continue to run my program.
What can I do?? |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Sun Jul 18, 2004 7:37 am |
|
|
Post your code... |
|
|
keup00 Guest
|
|
Posted: Sun Jul 18, 2004 7:58 am |
|
|
this is my function using a while loop. during this loop timer2 count and generate an interruption.
Quote: |
void niveau_1()
{ int i;
send_reg=0xAA;
buffer=0xAA;
for (i=0; i<16; i++)
{ while(buff_flag==0)
{ }
buffer=0xAA;
buff_flag=0;
}
}
void niveau_0()
{ int i;
send_reg=0x00;
buffer=0x00;
for (i=0; i<16; i++)
{ while(buff_flag==0)
{ }
buffer=0x00;
buff_flag=0;
}
}
|
this is the interruption on timer2
Quote: |
void timer2_int()
{
output_bit(PIN_B3,shift_right(&send_reg,1,0));
send_count++;
if (send_count==8)
{ send_reg=buffer;
buff_flag=1;
send_count=0;
}
}
|
at each interrup LSB of send_reg is send on PIN_B3, and a bit counter increments.
during this time, fonction niveau_1 or niveau_0 is in the while loop, then as soon as buff_flag is set, it would escape from the loop and reload my send buffer
it works fine most the time, but if the interrup occured on the end of while loop, when it return from interrup PCL goes directly to out of the loop even if buff_flag=0
So, thank you very much for reading my post, and much more to gave me a solution.
++
keup
PS: here is all my code, in case you need it. but please note that I am a newbie in C programming for pic, and that this programme is juste a test to send RC5 code to receiver. I use asm to deal with interrup because timer2 reset each 86 cycles (to generate a 36Khz carrier with a 24MHz clock) so the build-in C interrupt was too long...
Quote: |
#include "C:\Electronique\reveil\C\reveil.h"
#if defined(__PCM__)
int save_w;
#locate save_w=0x7f
int save_status;
#locate save_status=0x20
#locate send_reg=0x70
#locate buffer=0x71
#locate send_count=0x72
#locate Flags=0x73
#bit buff_flag=Flags.0
#locate toggle=0x74
#byte status = 3
#bit zero_flag = status.2
#bit t0if = 0xb.2
void timer2_int()
{
// int8 send_count;
output_bit(PIN_B3,shift_right(&send_reg,1,0));
//if (bit_test(send_reg,send_count)==1)
// output_high(PIN_B3);
// else output_low(PIN_B3);
send_count++;
if (send_count==8)
{ send_reg=buffer;
buff_flag=1;
send_count=0;
}
}
#INT_GLOBAL
void isr() {
#asm
//store current state of processor
MOVWF save_w
SWAPF status,W
BCF status,5
BCF status,6
MOVWF save_status
// Save anything else your code may change
// You need to do something with PCLATH if you have GOTOs
// remember to check to see what interrupt fired if using more than one!!
// code for isr
#endasm
timer2_int();
#asm
bcf 0x0C,1 ; effacer flag interupt
// INCF counter,F
BTFSC zero_flag
// INCF (&counter+1),F
// restore processor and return from interrupt
SWAPF save_status,W
MOVWF status
SWAPF save_w,F
SWAPF save_w,W
#endasm
}
//#INT_TIMER2 // This function is called every time
//void clock_isr(int8 send_reg, int8 buffer, buff_flag)
//{ // timer 2 overflows (250->0), which is
// }
void niveau_1()
{ int i;
send_reg=0xAA;
buffer=0xAA;
for (i=0; i<16; i++)
{ while(buff_flag==0)
{ }
buffer=0xAA;
buff_flag=0;
}
}
void niveau_0()
{ int i;
send_reg=0x00;
buffer=0x00;
for (i=0; i<16; i++)
{ while(buff_flag==0)
{ }
buffer=0x00;
buff_flag=0;
}
}
void send_1()
{
niveau_0();
niveau_1();
}
void send_0()
{
niveau_1();
niveau_0();
}
void send_start()
{
niveau_0();
niveau_1();
}
void send_toggle()
{ //int toggle;
if (toggle==0)
{ toggle=1;
send_1();
}
else
{ toggle=0;
send_0();
}
}
void main()
{
send_count=0;
buff_flag=0;
send_reg=0;
buffer=0;
toggle=0;
//int8* send_reg=0;
//int8* buffer;
//int8 Flags;
//#bit buff_flag=Flags.0
SET_TRIS_B( 0xF2 );
setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,84,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
set_timer2(0);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
while(TRUE){
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
send_start();
send_start();
send_1();
send_1();
send_1();
send_1();
send_1();
send_1();
send_1();
send_1();
send_1();
send_1();
send_1();
send_1();
output_low(PIN_B3);
disable_interrupts(INT_TIMER2);
disable_interrupts(GLOBAL);
delay_ms(500);
}
}
|
|
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Sun Jul 18, 2004 2:19 pm |
|
|
It might not change anything but I would change the syntax from this
Code: | while(buff_flag==0)
{ } |
to
Code: | while(buff_flag==0); |
What you wrote may be technicaly correct but it does not work. Sometimes changing the syntax is all it takes to get things working. |
|
|
Guest
|
|
Posted: Mon Jul 19, 2004 11:38 am |
|
|
thank you but it doesn't works..... |
|
|
Ttelmah Guest
|
Re: bug with interrup during while loop (PCM 3.19) |
Posted: Mon Jul 19, 2004 2:44 pm |
|
|
keup00 wrote: | when I have an interrup during the last instruction of a while loop, PCL do not return at the beginning of the while (even with a true condition), but instead it exits the while and continu to run my program
what can I do?? |
I suspect the problem is your 'int global' handler does not save enough. Look at the assembler generated for the 'shift' instruction, being passed an address. This probably does a bank switch. You do not save the registers for these. The loop instruction for the while, also probably does a bank switch, so it the interrupt occurs in between the switches, the program goes off into the wrong part of memory.
_Whenever_ you stop using the standard functions, it becomes _your_ responsibility to verify that everything that needs to be done, is done. I'd suspect that if you remove the int_global handler, and let the compiler do it, the code will work fine. At this point, you then have the balancing act of deciding whether the time saved, is worth the extra work of checking what needs to be saved...
Best Wishes |
|
|
|
|
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
|