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

Asynchronous receiving routine

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







Asynchronous receiving routine
PostPosted: Wed Apr 02, 2008 3:41 am     Reply with quote

Hi all,

I'm trying to implement an asynchronous RS422 serial communication with a PIC18221 at 2.4575 Mbits/s.

I need to receive a 6 bytes message on the PIC. The problem is that with my present routine I need to add a delay of around 10 µs between the bytes. This is of course a problem for a 2.4575 Mbits/s serial.

Could you help my make this routine faster?

Here is my configuration and receiving routine:

#include "18F2221.H"
#include "global.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#use delay(clock=19660800)
#use rs232(baud=2457500,XMIT=PIN_C6,RCV=PIN_C7,BRGH1OK)

TXSTA =0xA6;
RCSTA =0x90;
BAUDCON =0x80;
SPBRGH =0x00;
SPBRG =0x01;

void receiveroutine(void)
{
while (!kbhit())
{
delay_us(10);
}
i=0;
timeout=0;
while ((timeout<40)&&(i<7))
{
if (kbhit()==1)
{
commande[i]=getc();
i++;
}
timeout++;
delay_us(1);
}
nbytes=i;
}
Matro
Guest







PostPosted: Wed Apr 02, 2008 4:20 am     Reply with quote

What happens if the delay_µs(10) is not present?
You wrote you wait for 6 bytes but in your code you're waiting for 7.

You have to better explain your problem and give more information about it. If you want that we help you to solve it, we have first to wemm know and understand it.

Matro.
vinfr
Guest







PostPosted: Wed Apr 02, 2008 4:29 am     Reply with quote

I do not wait for 7 bytes, it's just a test to stop the receiving routine in the case of an incorrect message lengh (>6).
Matro
Guest







PostPosted: Wed Apr 02, 2008 4:32 am     Reply with quote

Yes you wait for 7 bytes...
When i=0, 1, 2, 3, 4, 5 & 6.
And after you exit.

You can count it yourself, you wait for 7 bytes...

Matro.
Guest








PostPosted: Wed Apr 02, 2008 6:22 am     Reply with quote

Ok, If you want...but that's NOT the point Rolling Eyes

Someone else?
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Wed Apr 02, 2008 7:00 am     Reply with quote

First of all, as Matro said, you are staying in the loop until you receive 7 bytes, not 6. So that is an error that needs to be corrected. Secondly, you didn't answer Matro's question of why you think you need to wait 10 usec between bytes. Also, you are not waiting 10 usec. between bytes. You are waiting 10 usec after each kbhit() check at the beginning of a message. This wait has no effect. You might as well remove it and just check for the initial kbhit() as fast as you can:
Code:

  while(!kbhit())  {;}


Finally, you are trying to receive 6 (or 7) characters at 2.4575 Mbits/s, which is 245,750 bytes per second, which means that each character takes about 4 usec. I don't know what clock speed you are running your PIC at, but it probably takes more than 4 usec. to go once around the loop. This again highlights the reason for removing the delay_us(10) in the initial wait for kbhit(), because as it is, you can receive 2 characters and be in the middle of receiving the third character before you ever get arround to checking kbhit() again.

It looks like the only reason for having an explicit initial wait for kbhit() is so that you can wait for the first byte of a message without any time-out, but then once the first byte has been received, you can impose a time-out on finishing the message. Here is how I would do it:

Code:

void receiveroutine(void)
{
  i = 0;
  timeout = 40;
  while ( !bit_test(PIR1,RCIF) ) {;}  //..initial wait..
  do
  {
    if( bit_test(PIR1,RCIF) )
    {
      commande[i] = RCREG;   //..equivalent of getc()..
      ++i;
      if(i == 6) break;
    }
  }while(--timeout);
  nbytes=i;
}


Make sure that both i and timeout are declared as bytes, not int16. Note that for speed I have eliminated all library function calls and replaced them by their direct register access equivalents. This has a hope of being able to receive a character every 4 usec. if your clock speed is fast enough. Also you will notice there are no more explicit calls to any delay function. Instead I am counting on the loop code execution time to provide the timeout delay. If you want to fine-tune the timeout, then I would just count instruction cycles in the disassembly of this code to determine the round-trip time for one loop iteration in which RCIF is not set (that is the norm). Then set the initial timeout so that it provides the desired timeout. Hopefully this setting is non-critical. Putting the timeout check at the end of the loop and making it a downcounter instead of an upcounter allows a compiler optimization that you would not get otherwise. And checking for i<6 need not be done all the time - only when you get a character. So I moved that check inside the block where you handle receiving a character. I hope this helps.

Robert Scott
Real-Time Specialties
Guest








PostPosted: Wed Apr 02, 2008 7:47 am     Reply with quote

Anonymous wrote:
Ok, If you want...but that's NOT the point Rolling Eyes

Someone else?

Maybe it is...
And you don't answer the most interesting question : what happens if you remove the "delay_µs(10)"?...

Matro
Guest








PostPosted: Thu Apr 03, 2008 2:10 am     Reply with quote

Thanks a lot, Robert. Surprised
The oscillator frequency is 19.6608 MHz.

Your code contains good improvements I'm going to test.
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