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

RS232 Interrupt problem~~

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



Joined: 08 Nov 2004
Posts: 11

View user's profile Send private message

RS232 Interrupt problem~~
PostPosted: Mon Nov 08, 2004 7:42 pm     Reply with quote

Hello all~! I am a student and currently I am doing a project using RS232 interrupt. I did a test on this (code below) and found that the interrupt was working only for the first time. When it returned to the main function and I send 'c' again for second time interrupt, it won't work anymore. Any problem with my code?

Code:

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#int_rda
void serial_isr() {
   char value;

   value=getc();

   if(value=='c')
   {
        output_high(PIN_D0);
        output_high(PIN_D1);
   }
}

void main()
{
   enable_interrupts(global);
   enable_interrupts(int_rda);

   printf("Enter 'c' \r\n");

   do
   {
         output_high(PIN_D0);
         delay_ms(300);
         output_low(PIN_D0);
         delay_ms(300);
         output_high(PIN_D1);
         delay_ms(300);
         output_low(PIN_D1);
         delay_ms(300);
   } while (TRUE);
}


Thx a lot~!!
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Nov 08, 2004 9:29 pm     Reply with quote

I am not sure if you have these leds flashing just to test interrupt or if needed for your actual project. If this is just to test interruppts then here is an alternative you might want to try.

Code:
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

bit found_it;

#int_rda
void serial_isr() {
   char value;

   value=getc();
   if(value=='c')
        found_it = true;
}


void main()
{
   found_it = false;
   enable_interrupts(global);
   enable_interrupts(int_rda);

   printf("Enter 'c' \r\n");

   do
   {
         if (found_it)
                  {
                  found_it = false;
                  output_high(PIN_D0);
                  output_high(PIN_D1);
                  delay_ms(300);
                  }                 
         output_high(PIN_D0);
         delay_ms(300);
         output_low(PIN_D0);
         delay_ms(300);
         output_high(PIN_D1);
         delay_ms(300);
         output_low(PIN_D1);
         delay_ms(300);
   } while (TRUE);
}

_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Twitie



Joined: 08 Nov 2004
Posts: 11

View user's profile Send private message

PostPosted: Mon Nov 08, 2004 10:18 pm     Reply with quote

Thx asmallri ~ Very Happy

The code works. However, the "bit found_it;" cannot be declared. I change it to "boolean found_it;" and it works.

Anyway, I wonder why my code is not working since both codes are logically the same.
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Mon Nov 08, 2004 10:27 pm     Reply with quote

Try 'int1' instead of 'bit'.
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Nov 08, 2004 11:38 pm     Reply with quote

Quote:
Anyway, I wonder why my code is not working since both codes are logically the same.


I didn't go through it before because I dod not know what you were trying to achieve. The original code used a function both inside and outside the interrupt hander. Some of the CCS code is non rentrant because a local variable used by the handler would be overwritten by the interrupt hander using the same functions. The compiler deals with this by adding a disable interrupt instruction to the fuction outside the interrupt handler. I believe (but do not know for sure) that this only happens when the function appears both inside and outside an interrupt handler. I do not know if this is the case with output_xxxx() functions - you would need to look into the .lst file to see what the compiler is doing. However the output_xxxx() functions contain multiple lines of assembler and you are interrupting this code. There are scenarios where this can cause problems as output ports may not be setback to the same state they were in prior to the interrupt but I do not know if this is happening in this case - again you would need to examine the .lst file to see if this is possible.

The real difference is the use of the flag in the new version. If the flag is set then you are going to set both LEDs outputs high and they will remain high for 300ms so you will see them. In the original version you interrupt handle could set the output high but the outputs then could be immediatley changed by the mainlie code on return from interrupt in which case you would not be able to see anything happening. In other words the interrupt handle in the new version does not do the "grunt work" it sets a flag and the mainline does the work.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Tue Nov 09, 2004 1:36 am     Reply with quote

asmallri wrote:

I didn't go through it before because I dod not know what you were trying to achieve. The original code used a function both inside and outside the interrupt hander. Some of the CCS code is non rentrant because a local variable used by the handler would be overwritten by the interrupt hander using the same functions. The compiler deals with this by adding a disable interrupt instruction to the fuction outside the interrupt handler. I believe (but do not know for sure) that this only happens when the function appears both inside and outside an interrupt handler. I do not know if this is the case with output_xxxx() functions - you would need to look into the .lst file to see what the compiler is doing. However the output_xxxx() functions contain multiple lines of assembler and you are interrupting this code. There are scenarios where this can cause problems as output ports may not be setback to the same state they were in prior to the interrupt but I do not know if this is happening in this case - again you would need to examine the .lst file to see if this is possible.


This is not the case for output_xxxx() functions since they are always implemented as inline.

I'm suspecting the way the original code changed the RD0 and RD1 is the culprit. They were toggled both inside the ISR and in the main(), so in the event of an interrupt happening, it would be difficult to distinguish what was actually changing them. They may have been high due the code in the main() while the ISR also set them high.

In the original code change your ISR to the code below and see if RD2 toggles everytime you press 'c'.

Code:
#int_rda
void serial_isr() {
   char value;

   value=getc();

   if(value=='c')
         output_toggle(PIN_D2);
}
 
Guest








PostPosted: Tue Nov 09, 2004 3:23 am     Reply with quote

I tried and it is working~ thx a lot guys! thx for helping. Very Happy
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