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 support@ccsinfo.com

Echoing characters with interrupts via rs232 on pic18f452

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



Joined: 08 Oct 2003
Posts: 4

View user's profile Send private message

Echoing characters with interrupts via rs232 on pic18f452
PostPosted: Thu Oct 09, 2003 8:41 am     Reply with quote

I'm sending some data (123456789\r) repeatedly from my pc at 38400, data bits=8, stop bits 1 parity=none. When the PIC sees a CR it echoes the entire contents of the buffer to the pc. What I don't understand is that every second transmission echoes garbage back to my pc (ex: 123456789 then 1#$*@! then 123456789 back again). Is there something wrong with my interrupt routine? When typing in the data from hyperterm everything is fine but it fails when it's being streamed. I tried every other baud rate and I still get sporadic garbage. Just in case any of you want to know, I'm using a max232.

Thanks,

Here's my example code.

#if defined(__PCH__)
#include <18F452.h>
#use delay(clock=19660800)
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#endif


#define BUFFER_SIZE 128
BYTE buffer[BUFFER_SIZE];
BYTE tail = 0;
BYTE receivedFrame = 0;


#INT_RDA
void serial_isr()
{
buffer[tail] = getc();
if(buffer[tail] == '\r' || tail == (BUFFER_SIZE - 1))
{
receivedFrame = 1;
disable_interrupts(GLOBAL);
}
else
{
tail++;
}
}

void main()
{
BYTE head = 0;
enable_interrupts(global);
enable_interrupts(int_rda);

do
{
if(receivedFrame == 1)
{
while(head <= tail)
putc(buffer[head++]);

head = tail = 0;
receivedFrame = 0;
enable_interrupts(global);
}
}
while (TRUE);
}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Thu Oct 09, 2003 8:56 am     Reply with quote

Try disabling the rda int. The global int will be restored by hardware on the return from int instruction.

Code:

#if defined(__PCH__)
#include <18F452.h>
#use delay(clock=19660800)
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#endif


#define BUFFER_SIZE 128
BYTE buffer[BUFFER_SIZE];
BYTE tail = 0;
BYTE receivedFrame = 0;


#INT_RDA
void serial_isr()
{
  buffer[tail] = getc();
  if(buffer[tail] == '\r' || tail == (BUFFER_SIZE - 1))
  {
    receivedFrame = 1;
    disable_interrupts(int_rda);
  }
  else
  {
    tail++;
  }
}

void main()
{
  BYTE head = 0;
  enable_interrupts(global);
  enable_interrupts(int_rda);

  while (TRUE)
  {
    if(receivedFrame == 1)
    {
      while(head <= tail)
        putc(buffer[head++]);
 
      head = tail = 0;
      receivedFrame = 0;
      enable_interrupts(int_rda);
    }
  }
 
}
ProgGuy



Joined: 08 Oct 2003
Posts: 4

View user's profile Send private message

PostPosted: Thu Oct 09, 2003 11:25 am     Reply with quote

I still have the same problem after changing the GLOBAL to INT_RDA. Thanks for the quick reponse though.
Ttelmah
Guest







PostPosted: Thu Oct 09, 2003 12:08 pm     Reply with quote

ProgGuy wrote:
I still have the same problem after changing the GLOBAL to INT_RDA. Thanks for the quick reponse though.


There are a series of things that might/will cause some problems, but I cannot see what is immediately causing the 'every second time' problem.
The first is that since you disable interupts, you should really 'flush' the receive buffer in the chip, before re-enabling, or some garbage may result from this.
The second, is that because you are using the hardware UART, you should really check for the output buffer having emptied, before re-enabling the interrupts (there may be a couple of characters still 'in transmission', when you start looking for the incoming characters).
It will be quicker in the interrupt code, to use a 'temporary' character, and code as:

buffer[tail++]=temp=getc();
if (temp=='\r' || tail>=BUFFER_SIZE)

This is because 'array accesses', are relatively slow, involving the addition of the offset, and then access through the indirect register I/O, while a simple variable is directly accessed.
I would test for tail, being >= to BUFFER_SIZE-1, since it is always safer in case the value is 'unexpected' at some point.
I would also clear the RDIF bit, before re-enabling the interrupt, since otherwise if any reception has occured, there will be an immediate interrupt on re-enabling the interrupt, and possible garbage reception from this.

Best Wishes
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Thu Oct 09, 2003 12:19 pm     Reply with quote

Quote:

I would also clear the RDIF bit, before re-enabling the interrupt, since otherwise if any reception has occured, there will be an immediate interrupt on re-enabling the interrupt, and possible garbage reception from this.


The RDIF bit is read only and is cleared when the RCREG is read. To clear the int you probably have to do something like:
Code:

if (kbhit())
  (void)getc();


Quote:

When typing in the data from hyperterm everything is fine but it fails when it's being streamed.

Are you sure that the program that you are using to stream the data is working correctly? Can you feed this output of this program back through Hyperterminal and see it correctly? What happens if you cut and paste with Hyperterminal? Does it fail also?

Mark
ProgGuy



Joined: 08 Oct 2003
Posts: 4

View user's profile Send private message

PostPosted: Thu Oct 09, 2003 12:39 pm     Reply with quote

Mark,

The driving program works fine. I get the same result if I paste blocks of text in hyperterm. I'm still working on some previous response and will post my results shortly.

Thanks,
ProgGuy
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