View previous topic :: View next topic |
Author |
Message |
Ringo42
Joined: 07 May 2004 Posts: 263
|
Serial port weirdness |
Posted: Tue Aug 08, 2006 8:12 am |
|
|
I'm using a pic18f452 at 20Mhz. I have a max232 chip onboard and use a standard serial cable to talk to my computer I'm not using any handshaking at all. I send commands to my pic like "pwm 1:50 2:50" followed by a carriage return '\r'. I can send commands all day using hyper terminal and it works perfectly. However If I use a VB or C# program to send the exact same command it works maybe %50 of the time, usually less than that. I'm hoping this is not a CCS or a pic issue, but I can't figure out what is different between the 2 ways of doing it. Has anyone here ever had a similar problem?
Here is my setup stuff
#include "18f452.h"
#fuses hs,nowdt,noprotect,put
#device *=16
#device adc=10
#use delay(clock=20000000)
#priority rb,ext,TIMER2 //left side
...
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7,errors,bits=8,parity=N)
and here is my serial int routine
#int_rda
void serial_int_routine()
{
int incoming_byte; // stores incoming byte from Master
static int buffer_index=0; // stores index point in serial buffer.
int i;
// Read incoming byte:
incoming_byte = tolower(getc());
if (curBuffId == 0)
{
SERIAL_BUFFER_0[buffer_index]=incoming_byte;
}
else if (curBuffId == 1)
{
SERIAL_BUFFER_1[buffer_index]=incoming_byte;
}
// Now it's safe to stuff the byte in the buffer,
// and increment the buffer index:
//SERIAL_BUFFER[buffer_index]=incoming_byte;
buffer_index++;
// End of command, set flag to process the command:
if(incoming_byte =='\r')
{
int_flag=1;
buffer_index=0;
// Switch Buffers:
if (curBuffId == 0)
{
curBuffId = 1;
SERIAL_BUFFER = SERIAL_BUFFER_0;
}
else if (curBuffId == 1)
{
curBuffId = 0;
SERIAL_BUFFER = SERIAL_BUFFER_1;
}
}
}
when I get a \r I set a flag then my main routine checks for the flag and services it later.
Does anyone see anything strange I'm doing?
Just in case anyone wonders, the c# line looks like this:
sp.Write("pwm 1:-99 2:-99\r");
Any help would be greatly appreciated.
Thanks
Ringo _________________ Ringo Davis |
|
|
Ringo42
Joined: 07 May 2004 Posts: 263
|
|
Posted: Tue Aug 08, 2006 8:29 am |
|
|
After reading another posters question about using a software uart, I have to ask if I'm doing this correctly?
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7,errors,bits=8,parity=N)
Since the pins I'm using are part of a hardware UART. Should I be declaring it differently, or does the compiler check to see if it is a hardware uart and then does it one way and if the pins declared above are not then it sets up a SW uart?
Ringo _________________ Ringo Davis |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Tue Aug 08, 2006 8:49 am |
|
|
If you have mapped the TX and RX pins to the same pins used by the hardware UART and have selected 8 bits it will use the hardware UART unless you specifically force it to use the SW UART.
You have several low priority interrupt handlers including the serial receive handler. Chances are you are losing characters because you are spending too long inside other handlers. A better way to do this is to use high priority interrupts for the INT_RDA (specify the fast option) note that if you are using external INT0 is can only be a high priority interrupt. This means you will have two high priority interrupt handlers.
There are tricks to doing this, amungst them you have to make sure you either preserve all registers as used by the handler. You could simplify the ring buffer management - at the moment is uses more registers than is necesary.
You could buy the source code for such a handler (did I mention I sell source code for this capability) :-) _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Ringo42
Joined: 07 May 2004 Posts: 263
|
|
Posted: Tue Aug 08, 2006 9:16 am |
|
|
Thanks, I'll try the FAST thing and see if it helps. I'll email you offline about your routines that you sell.
Thanks
Ringo _________________ Ringo Davis |
|
|
Hans Wedemeyer
Joined: 15 Sep 2003 Posts: 226
|
Re: Serial port weirdness |
Posted: Tue Aug 08, 2006 9:48 am |
|
|
Your version of Hyperterm may have a delay set between sending characters, and your VB or C# may not be delaying between chars !
Try adding a Sleeep(25) in the VB or C# code between sending each char.
Another point:
Your PIC ISR is doing a lot of work everytime it receives a char.
Suggestion for reworking your ISR.
Stuff the recieved bytes into a buffer, and check each byte to see if it is a '\r'.
Then set a global flag to indicate when the '\r' has been recieved and process the buffers worth of data outside of the ISR, somewhere in your main() loop.
If you cut down on the ISR code the PIC hardware UART will work very well, and require less delay between chars.
Hans W |
|
|
Ringo42
Joined: 07 May 2004 Posts: 263
|
|
Posted: Tue Aug 08, 2006 9:53 am |
|
|
THE ISR used to be very short, doing exactly what you described. It was changed to flip-flop the buffers to see if it would help with this problem. I'll try adding the delay in the C# and see if that helps. I'm hoping making the int FAST will also help. I'd rather fix it in the FW than in the C# program.
Thanks
Ringo _________________ Ringo Davis |
|
|
|