View previous topic :: View next topic |
Author |
Message |
chingB
Joined: 29 Dec 2003 Posts: 81
|
Incoming Serial Data Inquiry |
Posted: Fri May 21, 2004 2:18 am |
|
|
Hi,
I have a serial comm application between the PC and PIC...
The PC sends a series of 10bytes data.... and my PIC receive the first 10bytes data and process it... while processing, it can also receive another set of 10bytes data.... after processing the first 10bytes it process the 2nd 10bytes receive... this will repeat the process until the last 10bytes is process...
Would this be possible? Anybody in the forum who can share some lights on this implementation or maybe a sample code snippet.
Thanx |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Fri May 21, 2004 6:45 am |
|
|
You'll need to write an interrupt driven code to receive each indivisual byte and store in a buffer in the UART interrupt service routine. This way you won't miss any data while your are processing the previous bytes of the received packet. |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Fri May 21, 2004 6:51 am |
|
|
I'm always concerned about the possibility of one interrupt delaying the operation of another, so the way I write code pretty much always uses just one interrupt, which is a repeating timer that operates faster than characters can come in over the serial port. There's a global array that is used as a buffer for incoming characters, and usually I give this a size of 16 or 32 so I can use a fast algorithm to increment the index. Actually there are two indexes, one for "push" and one for "pop":
Code: |
int incoming[32]; // Note that this is a power of 2
int push;
int pop;
|
Then in the interrupt the code is as follows:
Code: |
if (bit_test(rcif)) // Seen an incoming byte?
{ // Yup
incoming[push++] = rcreg; // Store it
bit_clear(push, 5); // This lets us count 0-31 then wrap
}
|
Then in the main() function there's a continuous loop running, which checks everything that needs checking and includes this:
Code: |
pop = 0;
push = 0;
// Insert code to start the timer
while(1)
{
// Other stuff can appear here
if (pop != push) // Here's the check for new data
{ // Got something
new_data = incoming[pop++];
// Insert code to do whatever we do with new data
bit_clear(pop, 5); // As before, count to 31 then wrap
}
}
|
Obviously, you need to know certain things. How rapidly will data come in, how fast will main() do what it has to do, including processing a new byte (and I assume that the last byte in a packet will take extra time, as the entire packet then needs processing). The critical factor is to make sure that the 32-byte buffer doesn't overflow. If there's danger of this, as might happen if there is some task in main() that might take a very long time, you'd have to consider going to check the communications buffer during the operation of that task. But in general I've been very successful with this kind of program structure.
Note that if you have just the one interrupt, you've got a "perfect" clock where the operation never gets delayed by any other interrupt. You can divide that clock down to create slower timers for any purpose the program needs. |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Fri May 21, 2004 7:55 am |
|
|
John P wrote: |
Code: |
if (bit_test(rcif)) // Seen an incoming byte?
{ // Yup
incoming[push++] = rcreg; // Store it
bit_clear(push, 5); // This lets us count 0-31 then wrap
}
|
|
I have never seen a bit clear used like that to make a number wrap. That's a nice idea. |
|
|
chingB
Joined: 29 Dec 2003 Posts: 81
|
|
Posted: Sat May 22, 2004 2:36 am |
|
|
Thanx guys.... you gave me an idea on handling incoming data...
btw, the example together with the compiler --- EX_SISR would help in my application?
Thanx |
|
|
|