|
|
View previous topic :: View next topic |
Author |
Message |
JerryR
Joined: 07 Feb 2008 Posts: 167
|
RS232 Errors not working |
Posted: Fri Apr 04, 2008 3:12 pm |
|
|
We're using a PIC18F4525, v3.249 PCWH
Even though we have used the Errors in the USE rs(232) below. we are not able to clear an int _rda lockup problem. We understand that if a rx buffer overflow problem occurs subsequent interrupts from int_rda are discontinued. However, we believe that the use of the ERRORS in the use232 statement would reset the overflow issue allowing continued int_rda action.
Is this true?
Code showing use of Errors option
Code: |
#include <18F4525.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT
#use delay(clock=10000000)
#use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, ERRORS, stream=GPS)
#use rs232(baud=4800, xmit=PIN_D7, rcv=PIN_D6,stream=PC)
|
|
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Fri Apr 04, 2008 3:22 pm |
|
|
Kind of right.
Quote: | if a rx buffer overflow |
no its when your interupt doesn't get the data from the usart (RCREG) fast enough. I normally think of a buffer as something I set
up in firmware
eg: the RX_BUF below..
Code: | //=======================RXisr============================//
//Takes RX data from a stream and puts it into a buffer via interrupts
#INT_RDA
void RXisr(void)
{
idle_bus=FALSE;
set_timer1(Timer1_Initial_Value);
RX_BUF[rx_indx]=RCREG;
rx_indx++;
if (rx_indx==MAXHEADER+MAXDATA+1) // check for buffer overflow
{
bit_set(ERRORS,2);//set error flag bit 2 for RXbuffer overflow
}
if (OERR)
{
bit_set(ERRORS,0);//set error flag bit 0 for USART overflow
CREN = 0;
CREN = 1;
}
}
|
but errors is to allow for clearing the USART overflow error.
18.2.2 page 215 item 9 of the 18F4525.pdf |
|
|
Ttelmah Guest
|
|
Posted: Fri Apr 04, 2008 3:33 pm |
|
|
'ERRORS' will clear the error, but _only when a character is read_.
If you come into an interrupt, and the service time is slow enough that the error triggers between reading the character at the start of the routine, and exiting the routine, the interrupt, won't trigger again, and the UART will still be hung.
If you re-code the interrupt handler like:
Code: |
#INT_RDA noclear
void int_handler(void) {
int temp;
do {
temp=getc();
clear_interrupts(INT_RDA);
//store your character here
} while(kbhit());
}
|
The ERRORS problem should disappear.
Treitmey's solution can still give the same problem, if data is arriving really fast, and the loop time into the handler is long, but it will massively reduce the likelyhood of this happening (there are only a couple of instruction times in the entire loop, where it can occur).
The most likely cause of problems in all cases, is a interrupt routine that is much slower than it should be...
Best Wishes |
|
|
KU5D
Joined: 10 Feb 2008 Posts: 46 Location: Asheville, North Carolina
|
|
Posted: Sun Apr 06, 2008 8:01 pm |
|
|
What if we want to hold off on the hardware usart and do other things? We can go without data from the port for a few seconds, but even if we disable the INT_RDA, if a character hits the port and we don't read it, it hangs the port and the interrupt no longer fires. I've tried something cheesy like:
char junk;
if(kbhit(thatPort)) { junk = getc(thatPort); }
That doesn't work since the event has long since past...seems once the buffer is full, life is over. I don't want to directly call getc in case there's nothing connected to the port...that'd hang us forever as well.
Is there a way to clear the buffer if we find it full when we get to it? _________________ Confidence is the feeling you have right before you fully understand the situation... |
|
|
Ttelmah Guest
|
|
Posted: Mon Apr 07, 2008 4:01 am |
|
|
What you post should clear the error, but would need to be in the 'main', before you re-enable the interrupt.
However, Treitmey's solution is also good:
Code: |
#byte RCSTA=0xFAB
#bit CREN=RCSTA.4
#byte INTCON=0xFF2
#bit RBIF=INTCON.0
#byte RCREG=0xFAD
void restart_RS232() {
int8 temp;
CREN=false; //turn off the UART
while (RBIF) temp=RCREG; //ensure buffer is flushed
CREN=true; //re-enable the receive - clears the error
enable_interrupts(INT_RXD);
}
|
This will clear both overrun errors, and framing errors, then re-enable the interrupts.
Best Wishes |
|
|
|
|
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
|