![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
Unexpected behavior of the RCSTA register |
Posted: Tue May 15, 2007 6:40 pm |
|
|
Colleagues,
To debug the serial communication between the host PC and the PIC, I’m monitoring the RS232_ERRORS variable. According to one of the PCM’s posts RS232_ERRORS mirrors the RCSTA register, except for the LSB.
Until the PIC had received the first serial byte, RCSTA=0x00.
After the PIC had received the first serial byte, RCSTA=0x90. The SPEN and CREN become and remain set. According to the datasheet these bits enable synchronous reception and transmission. I don’t touch these bits in my code. What could be setting them
Code: | #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=pcrs232,errors) |
PIC18LF4320, 8MHz internal RC, Vcc = +5V
CCS 3.240
ICD-U40, f/w 1.39 _________________ Read the label, before opening a can of worms. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue May 15, 2007 7:45 pm |
|
|
Those bits need to be enabled for the UART to operate. I assume you're
looking at the RCSTA register in a debugger window. The power-on
reset state of RCSTA is 0x00. The compiler sets it to 0x90 in the
start-up code, at the beginning of main(). I think your problem may
be due to some debugger issue, or the interpretation of the debugger
output. Here is the register bit description from the data sheet:
Quote: |
SPEN: Serial Port Enable bit
1 = Serial port enabled (configures RX and TX pins as serial port pins)
0 = Serial port disabled
CREN: Continuous Receive Enable bit
Asynchronous mode:
1 = Enables receiver
0 = Disables receiver
|
|
|
![](templates/subSilver/images/spacer.gif) |
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Tue May 15, 2007 8:36 pm |
|
|
PCM programmer wrote: | I assume you're looking at the RCSTA register in a debugger window. |
Actually, I'm fprintf()ing it.
This was a part of a an effort to debug another problem. I have an serial ISR that bufferizes the packets. Each packet starts with $ and ends with CRLF. This code was working a few days ago, and it had worked in a previous project too. But now, when I send a packet of bytes back-to back, the PIC dosn't recognize the packet. When I send one byte at a time, the packet is recognized. I thought that 9600 is a modest baud rate and the PIC should be able to handle it. There are no otherrrupts lurking on the backbround.
Code: | #INT_RDA
void comm_isr( void )
{
structBuff* pTemp; // used for buffer swapping
char c;
c = fgetc(pcrs232);
switch ( c )
{
case '$': // '$' - beginning of the command
g_iCommFlags = COMM_CMD; // set start of command flag, reset others
g_pIncompleteCmd->len = 0; // zer0 new command buffer length
break;
case 10: // <LF> - possible end of the packet
g_iCommFlags |= COMM_FND_LF; // set the <LF> flag
break;
case 13: // <CR> - possible end of the packet
g_iCommFlags |= COMM_FND_CR; // set the <CR> flag
break;
default:
if (g_iCommFlags & COMM_CMD) // if we have already received the '$'
{
g_pIncompleteCmd->buff[g_pIncompleteCmd->len] = c; // store new character in the buffer
++g_pIncompleteCmd->len; // increment the buffer length
g_pIncompleteCmd->len %= BUFFER_LEN; // limit bounds
}
}; // switch (c)
// test to see if we have a complete command in the buffer
if ((g_iCommFlags & (COMM_CMD | COMM_FND_CR | COMM_FND_LF)) ==
(COMM_CMD | COMM_FND_CR | COMM_FND_LF))
{
g_iCommFlags = COMM_FND_CMD; // set command found flag, reset others
// perform buffer swap
// swap pointers to "complete" and "incomplete" buffers
// NOTE:
// This approach assumes the foreground task has finished processing
// the previous buffer. Dynamic memory allocation or a FIFO will
// be needed if packets arrive in bursts.
pTemp = g_pCompleteCmd;
g_pCompleteCmd = g_pIncompleteCmd;
g_pIncompleteCmd = pTemp;
g_pIncompleteCmd->buff[0] = 0; // clear past command
}
} // comm_isr() |
Code: | void main()
{
...
while (1)
{
...
if (g_iCommFlags == COMM_FND_CMD) // check for the communications buffer
{ // command found
beep();
process_command(g_pCompleteCmd); // process command
g_iCommFlags &= ~COMM_FND_CMD; // reset command found flag
}
}
} |
The declaration and initialization of the buffers have been omitted. _________________ Read the label, before opening a can of worms. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue May 15, 2007 9:58 pm |
|
|
You have a comment in your isr that says exactly what the problem is.
How long does the beep take ? Try commenting out that beep.
Also, doing an fprintf() for debugging, if it's more than just two chars,
will cause a delay in processing the packet of 1 ms per additional char.
This could cause you to get an overrun error. The error will be cleared
because you're using ERRORS, but you'll lose one or more chars.
If you want to eliminate the problem, use a large circular buffer (it can
be large, because you've got an 18F), and pull the received packet out
of that buffer into a local linear buffer for processing. |
|
![](templates/subSilver/images/spacer.gif) |
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Tue May 15, 2007 11:00 pm |
|
|
PCM programmer wrote: | How long does the beep take ? Try commenting out that beep. |
I’m sending the packets “by hand”, say, once a minute. There’s plenty of time for beeping. The intent is only to recognize packets, buffer and discard them; processing is not even attempted.
PCM programmer wrote: | The error will be cleared
because you're using ERRORS... |
That suggests that I need to remove ERRORS from #use rs232 and monitor (so that the error flags will not be cleared) and monitor OERR in RCSTA. _________________ Read the label, before opening a can of worms. |
|
![](templates/subSilver/images/spacer.gif) |
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Wed May 16, 2007 7:10 pm |
|
|
kender wrote: | PCM programmer wrote: | The error will be cleared because you're using ERRORS... |
That suggests that I need to remove ERRORS from #use rs232 and monitor (so that the error flags will not be cleared) and monitor OERR in RCSTA. |
I'm getting an overflow error. OERR gets set. Even when I send only 3 bytes in a burst after several seconds of silence.
The overflow occurs even if I remove the majority of the code from the ISR and keep only
Code: | #INT_RDA
void comm_isr( void )
{
structBuff* pTemp; // used for buffer swapping
char c;
c = fgetc(pcrs232);
} |
The new UART settings are:
Code: | #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=pcrs232) |
WDT is off _________________ Read the label, before opening a can of worms. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 16, 2007 11:22 pm |
|
|
I made a very short program with an #int_rda routine, and compiled
with your version and with vs. 4.037. I compared the .LST files and
I don't see any obvious differences that could cause a problem.
Of course, that assumes that 4.037 has no problems.
I think you should make a small test program using the Ex_sisr.c code,
and then send small packets to the PIC and see if they're echoed back correctly. Also, don't use streams, or any parsing code. Keep it simple. |
|
![](templates/subSilver/images/spacer.gif) |
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Thu May 17, 2007 12:06 am |
|
|
The problem has disappeared (at least for the time being), when DEBUG fuse was changed to NODEBUG. _________________ Read the label, before opening a can of worms. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|