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

bug with interrupt during while loop (PCM 3.19)

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







bug with interrupt during while loop (PCM 3.19)
PostPosted: Sun Jul 18, 2004 5:28 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jul 18, 2004 7:37 am     Reply with quote

Post your code...
keup00
Guest







PostPosted: Sun Jul 18, 2004 7:58 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jul 18, 2004 2:19 pm     Reply with quote

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








PostPosted: Mon Jul 19, 2004 11:38 am     Reply with quote

thank you but it doesn't works.....
Ttelmah
Guest







Re: bug with interrup during while loop (PCM 3.19)
PostPosted: Mon Jul 19, 2004 2:44 pm     Reply with quote

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
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