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
Sebastian



Joined: 01 Dec 2003
Posts: 21
Location: Milan Italy

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

RS232 INTERRUPT PROBLEM
PostPosted: Wed Jan 04, 2006 8:34 am     Reply with quote

HI ALL !!

I HAVE TRY TO MANAGE INTERRUPTS.

I MUST TURN ON RXLED ( IN MY CODE ) AFTER EVERY RX 232 INTERRUPT BUT IN THIS WAY I SEE LED ON ONLY AFTER THE SECOND
PUSH BUTTON .


SOMEONE CAN TELL ME A RIGHT WAY........


#if defined(__PCH__)
#include <18F452.h>
#include <string.H>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#endif

#include <input.c>

#define STX 0x02 // Start of Transmition
#define ETX 0x03 // End of Transmition
#define AD 0x55
#define SEMICOLON 0x3B

#define LED1 PIN_B0
#define LED2 PIN_B1
#define LED3 PIN_B2
#define LED4 PIN_B3
#define LED5 PIN_B4
#define LED6 PIN_B5
#define RFLED PIN_A1
#define RXLED PIN_A2
#define PUSH_BUTTON PIN_D0

//------------------------------------------------------------------------------

#define BUFFER_SIZE 9

//------------------------------------------------------------------------------

#DEFINE BUFFER_COMPARE

//------------------------------------------------------------------------------

// GLOBALS
static int8 char_rcved, data_valid, next_in;
static int8 buffer_overflow, stream_complete;
static int8 sermssg[BUFFER_SIZE];


/////////////////////////////////////////////////////////////////////

static int8 stringa[10]= {STX,0,0,0,1,1,SEMICOLON,AD,ETX};

// a string always ends with a NULL, so 9 char + NULL = [10]

////////////////////////////////////////////////////////////////////////

set_tris_b(0x00);
set_tris_d(0b11111111);
set_tris_a(0b00000000);

//------------------------------------------------------------------------------
#INT_RDA
void isr_serial_rcv()
{
char_rcved = getc(); // Get the incoming char

if ( char_rcved == STX )
{ next_in = 0; // Init the index
data_valid = TRUE; // Enable buffering
buffer_overflow = FALSE;
}

if ( data_valid )
{ sermssg[next_in] = char_rcved;
next_in++;

if ( next_in > BUFFER_SIZE ) // String longer than expected
{ data_valid = FALSE; // Stop buffering
buffer_overflow = TRUE;
}

if ( char_rcved == ETX )
{ data_valid = FALSE; // Stop buffering
stream_complete = TRUE;
}
}
}

void main()
{
delay_ms(400);
//set_tris_b(0x00);
//set_tris_d(0b11111111);
//set_tris_a(0b00000000);


stream_complete = FALSE;
enable_interrupts(GLOBAL);

while(1)
{
enable_interrupts( INT_RDA );

do{ // While stream_complete

do{
output_high(LED6);
delay_ms(200);
output_low(LED6);
delay_ms(200);
}while(input(PUSH_BUTTON));
(!input(PUSH_BUTTON));


output_b(0x00);
output_low(RXLED);
delay_ms(2000);

printf("\x2");
printf("0001wdloa;1;");
printf("\xFF");
printf("\x3");

//RX STX,0,0,0,1,1,SEMICOLON,AD,ETX RXLED ON

output_high(LED1);

delay_ms(2000);
////////////////////////////////// INTERRUPT
}while ( !stream_complete );


do{ // While stream_complete

do{
output_high(LED5);
delay_ms(200);
output_low(LED5);
delay_ms(200);
}while(input(PUSH_BUTTON));
(!input(PUSH_BUTTON));

output_b(0x00);
output_low(RXLED);
delay_ms(2000);

printf("\x2");
printf("0001wdloa;2;");
printf("\x80");
printf("\x3");

//RX STX,0,0,0,1,1,SEMICOLON,AD,ETX RXLED ON

output_high(LED2);

delay_ms(2000);
//////////////////////////////////INTERRUPT

}while ( !stream_complete );

if ( stream_complete )
{
stream_complete = FALSE; // IMPORTANT: If not the program re-enter

if ( !buffer_overflow )
{
disable_interrupts( INT_RDA );


#IFDEF BUFFER_COMPARE //////////////////////////////////////////////////////////

if (strcmp(stringa,sermssg))
{
output_high(RXLED);
}
#ENDIF //////////////////////////////////////////////////////////////////////////

} // if ( !buffer_overflow )

if ( buffer_overflow )
{// something wrong related to incoming string
output_b(0xff);
delay_ms(100); // Just to see a change in output_b
buffer_overflow = FALSE; // clear the fault !!!!
}

} // if ( stream_complete )

} // while(1)

} // void main()
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Jan 04, 2006 10:07 am     Reply with quote

First two remarks:
1) TYPING YOUR MESSAGE IN CAPITAL LETTERS IS CONSIDERED NOT POLITE.
2) Please use the 'code' button when posting code so the indenting of your code is kept intact.

I haven't checked all your code because the flow is hard to follow but I found two errors:
Code:
#define BUFFER_SIZE 9
.
.
.
  if ( data_valid )
  {
    sermssg[next_in] = char_rcved;
    next_in++;

    if ( next_in > BUFFER_SIZE ) // String longer than expected
    {
      data_valid = FALSE; // Stop buffering
      buffer_overflow = TRUE;
    }

    if ( char_rcved == ETX )
    { data_valid = FALSE; // Stop buffering
      stream_complete = TRUE;
    }
  }

- On reception of a message with length 10 or larger you will first overwrite data in memory at location sermssg[9] before detecting the message to be too long.
- In case of errors you will stop receiving and never set the stream_complete flag to TRUE. In your main() you are testing this flag in a while loop and your program loops forever...

Code:
      delay_ms(2000);
      ////////////////////////////////// INTERRUPT
This is terrible code! You have a nice interrupt routine receiving data in the background and then you are blocking your program for 2 seconds while waiting for a response???
Much nicer is a construction like this:
Code:
      timeout=0;
      do
      {
        delay_ms(10);
        timeout++;
      } while ((!stream_complete) && (timeout < 200));
Sebastian



Joined: 01 Dec 2003
Posts: 21
Location: Milan Italy

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

little help
PostPosted: Thu Jan 05, 2006 6:46 am     Reply with quote

Hi ckielstra.

I'm new in PIC programming ......can i ask you one advice ?

In my code I transmit two stream ,stream1 and stream2 after push_button.After every push_button ,(stream1 is a command),
I recive always the same nine caracters {STX,0,0,0,1,1,SEMICOLON,AD,ETX}; that sign the correct recive command from a board.

For to know if the command is arrived and processed I want turn on
RXLED .
What i must to do for this .
The interrupt routine see only the second return string not the first.
I can delete the input string and remove buffer overflow.
Have you any suggestions.
How can write compare and delete the string input message every time.

Thank you in advance
Code:
#if defined(__PCH__)
#include <18F452.h>
#include <string.H> 

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#endif

#include <input.c>

#define     STX        0x02  // Start of Transmition
#define     ETX        0x03  // End of Transmition
#define     AD         0x55 
#define     SEMICOLON  0x3B

#define     LED1         PIN_B0
#define     LED2         PIN_B1       
#define     LED3         PIN_B2
#define     LED4         PIN_B3
#define     LED5         PIN_B4
#define     LED6         PIN_B5
#define     RFLED        PIN_A1
#define     RXLED        PIN_A2
#define     PUSH_BUTTON  PIN_D0

//------------------------------------------------------------------------------

#define     BUFFER_SIZE 9

//------------------------------------------------------------------------------
 
#DEFINE  BUFFER_COMPARE

//------------------------------------------------------------------------------

// GLOBALS
static int8 char_rcved, data_valid, next_in;
static int8 buffer_overflow, stream_complete;
static int8 sermssg[BUFFER_SIZE];


/////////////////////////////////////////////////////////////////////

static int8 stringa[10]= {STX,0,0,0,1,1,SEMICOLON,AD,ETX};

// a string always ends with a NULL, so 9 char + NULL = [10]

////////////////////////////////////////////////////////////////////////

   set_tris_b(0x00);
   set_tris_d(0b11111111);
   set_tris_a(0b00000000);

 //------------------------------------------------------------------------------
#INT_RDA
void isr_serial_rcv()
{
  char_rcved = getc(); // Get the incoming char

  if ( char_rcved == STX ) 
     { next_in = 0;        // Init the index
       data_valid = TRUE;  // Enable buffering
       buffer_overflow = FALSE;
     }

  if ( data_valid )       
     { sermssg[next_in] = char_rcved;
       next_in++;           

       if ( next_in > BUFFER_SIZE ) // String longer than expected
          { data_valid = FALSE; // Stop buffering
            buffer_overflow = TRUE;
          }

       if ( char_rcved == ETX )
          { data_valid = FALSE; // Stop buffering
            stream_complete = TRUE;
          }
     }
}
 
void main()
{
   delay_ms(400);     
   stream_complete = FALSE;
   enable_interrupts(GLOBAL);

   while(1)
        {
       enable_interrupts( INT_RDA );

  do{ // While stream_complete

  do{
output_high(LED6);
  delay_ms(200);
output_low(LED6);
  delay_ms(200);
}while(input(PUSH_BUTTON));
     (!input(PUSH_BUTTON));


  output_b(0x00);
  output_low(RXLED);
  delay_ms(2000);

//STREAM 1
  printf("\x2");
  printf("0001wdloa;1;");
  printf("\xFF");
  printf("\x3");

//RX   STX,0,0,0,1,1,SEMICOLON,AD,ETX   RXLED ON

   output_high(LED1);

 
////////////////////////////////// INTERRUPT
 }while ( !stream_complete );


   do{   // While stream_complete

  do{
output_high(LED5);
  delay_ms(200);
output_low(LED5);
  delay_ms(200);
}while(input(PUSH_BUTTON));
     (!input(PUSH_BUTTON));

  output_b(0x00);
  output_low(RXLED);
  delay_ms(2000);
//STREAM 2
  printf("\x2");
  printf("0001wdloa;2;");
  printf("\x80");
  printf("\x3");

//RX   STX,0,0,0,1,1,SEMICOLON,AD,ETX   RXLED ON

   output_high(LED2);

 
//////////////////////////////////INTERRUPT

               }while ( !stream_complete );

        if ( stream_complete )
           {
            stream_complete = FALSE;  // IMPORTANT: If not the program re-enter
           
            if ( !buffer_overflow )
               {
                 disable_interrupts( INT_RDA );
         

#IFDEF BUFFER_COMPARE  //////////////////////////////////////////////////////////

                 if (strcmp(stringa,sermssg))
                    {
                     output_high(RXLED);
                                        }
#ENDIF //////////////////////////////////////////////////////////////////////////

          } // if ( !buffer_overflow )

        if ( buffer_overflow )
           {// something wrong related to incoming string
             output_b(0xff);
             delay_ms(100);    // Just to see a change in output_b
             buffer_overflow = FALSE; // clear the fault !!!!
       }   

      }   // if ( stream_complete )

    }     // while(1)
 
}     // void main()
litoman



Joined: 04 Nov 2005
Posts: 3

View user's profile Send private message

INT_RDA problem
PostPosted: Thu Jan 05, 2006 7:50 am     Reply with quote

Yes i think that there is a bug with INT_RDA in PIC 18F452 and 18F252 etc.
When the PIC go into interruption routine it never go out or it reset.
I have a same problem.
litoman



Joined: 04 Nov 2005
Posts: 3

View user's profile Send private message

INT_RDA problem
PostPosted: Thu Jan 05, 2006 8:04 am     Reply with quote

See

http://www.ccsinfo.com/forum/viewtopic.php?t=24945&highlight=18f252
Ttelmah
Guest







PostPosted: Thu Jan 05, 2006 8:23 am     Reply with quote

The original poster, is not using high priority interrupts, so the reference thread doesn't apply.
There is nothing wrong with INT_RDA, on the 452/252, I have sometyhing in excess of a couple of thousand units out in the field, using these chips, and interrupt driven I/O, without problems.

Now the code unfortunately, is almost illegible in places, because of the layout. However some bits leap out as potential problems. If the counter, gets to '9', it will not flag a buffer overflow (because the test, tests for the counter being greater than the buffer size), yet the byte received will go to sermssg[9], which will overwrite the buffer area,and may cause disaster.
What is this meant to do?
Code:

}while(input(PUSH_BUTTON));
(!input(PUSH_BUTTON));


The first line, is the termination statement for an earlier 'do', but the second line seems to have been left over from somewhere...

Tidy the code. Fix the buffer size fault, and if it still doesn't work, repost it (using the code button), and somebody may be then able to see what is wrong.

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Jan 05, 2006 4:46 pm     Reply with quote

The main problem in the program is that after sending a stream over RS232 there is no time allowed for the response to arrive.

Current implementation
Code:
do
{
  wait for button
  2 sec delay          <-- makes no sense here.
  send Stream1
} while (no response received)
Very likely the 2 second delay was supposed to be located after sending Stream1.

A better implementation would be
Code:
wait for button
send Stream1
while (no response received)
{
  // Do nothing (or blink a led)
}
jack
Guest







PostPosted: Thu Jan 05, 2006 11:15 pm     Reply with quote

Hi, I have a question about....RS232 and Timer0 interrupt...

I'm sending data over rs232 at 2400baud...at the same time timer0 overflow interrupt @ 64.5msec occurs through out, will the data be recieved safely??

Thanks
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Jan 06, 2006 3:07 am     Reply with quote

jack wrote:
Hi, I have a question about....RS232 and Timer0 interrupt...

I'm sending data over rs232 at 2400baud...at the same time timer0 overflow interrupt @ 64.5msec occurs through out, will the data be recieved safely??

Thanks
Please post new questions in a new thread.
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