|
|
View previous topic :: View next topic |
Author |
Message |
Anna
Joined: 29 Dec 2003 Posts: 4
|
FERR error |
Posted: Sun Mar 07, 2004 8:40 am |
|
|
Hi to all which read my message,
I have next question: I am used pic16f77 with hardware USART, baud rate 19200 and sometimes received framing error (FERR = 1) .Why is occur? All work right and suddenly this error? I am want to clear it, but unfortunally, when I write value to RCSTA to clear error - RCSTA in this moment receive again FERR. What I do wrong? This is code :
while (RCSTA & 0x06) // for FERR and OERR error
{
restart_wdt();
disable_interrupts(INT_RDA);
disable_interrupts(GLOBAL);
RCSTA = 0x80; // ???????????????? I cann't clear error
ch = RCREG;
ch = RCREG;
ch = RCREG;
RCSTA = 0x90;
X_Rx_Init();
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
}
void X_Rx_Init (void) // initialization of USART
{
BRG = 25; //BRG = 0x99 this is SPBRG , for baund rate 22=16h
//<6> = TX9 = 0 - selects 8 bit transmission
TXSTA = 0b00100110; //<2> = BRGH = 1 - high speed async. mode
//<5> = TXEN = 1 - transmit enable
RCSTA = 0b10010000; //<4> = CREN = 1 - enable continuous receive
//<7> = SPEN = 1 - serial port enable
enable_interrupts(INT_RDA);
}
Thank you for all answer.. _________________ Anna |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Sun Mar 07, 2004 10:59 am |
|
|
This is how I catch and act on errors.
Code: | { if(bit_test(RS232_ERRORS,2)) // Found Framing Errors
{ ++ChA_Errors;
if(ChA_Errors & 8)
{ ChA_Errors=0;
ChA_Change_Baud();
}
}
|
You have to include the errors directive in the #use statement for the port. |
|
|
Guest
|
|
Posted: Sun Mar 07, 2004 1:25 pm |
|
|
Neutone wrote: | This is how I catch and act on errors.
Code: | { if(bit_test(RS232_ERRORS,2)) // Found Framing Errors
{ ++ChA_Errors;
if(ChA_Errors & 8)
{ ChA_Errors=0;
ChA_Change_Baud();
}
}
|
You have to include the errors directive in the #use statement for the port. |
Thank you for an answer,Neuton,
but I don't use '#use', I want to catch errors, send bytes and receive not by functions of compiler - throught TXREG and RCREG. You think this error occur if baud rate change from 19200 to another? After I catched this error I reinit USART, but I continue receive FERR and this is not allow me reset RCSTA register. Why this is occur?
After reset of the programm FERR not appear and all work, but after sometimes FERR turn back. |
|
|
Ttelmah Guest
|
|
Posted: Sun Mar 07, 2004 2:55 pm |
|
|
Anonymous wrote: | Neutone wrote: | This is how I catch and act on errors.
Code: | { if(bit_test(RS232_ERRORS,2)) // Found Framing Errors
{ ++ChA_Errors;
if(ChA_Errors & 8)
{ ChA_Errors=0;
ChA_Change_Baud();
}
}
|
You have to include the errors directive in the #use statement for the port. |
Thank you for an answer,Neuton,
but I don't use '#use', I want to catch errors, send bytes and receive not by functions of compiler - throught TXREG and RCREG. You think this error occur if baud rate change from 19200 to another? After I catched this error I reinit USART, but I continue receive FERR and this is not allow me reset RCSTA register. Why this is occur?
After reset of the programm FERR not appear and all work, but after sometimes FERR turn back. |
There are a series of comments.
1) If you are doing a 'DIY' error handler, you have to handle both FERR, and OERR. For FERR, simply reading the input resets the error. For OERR, you have to disable continuous receive, remove a character from the input buffer, and re-enable the receive. Remember that both errors can happen together.
2) Once a framing error takes place, you have to look at how your transmission is laid out to speed recovery. If the data stream is pretty continuous, it can take several characters before the UARt will resynchronise to the start bit (it depends on the data patterns in the incoming data). If you have a gap in the transmitted data of at least one character time occassionally, this forces the detection to once more find the start bit.
3) You need to look at why framing errors are occuring. These basically imply that the communication is probably mistimed if they happen frequently. The allowable timing error, will depend on the sampling strategy at both ends of the link. Any timing errors, are in the worst case 'additive', so if the transmission is mis-timed by 2%, and the receiver is mis-timed in the opposite direction by 3.5% (say), the total may be enough to cause problems. If you are changing baud rates, you _will_ allmost certainly see at least one framing error during the change. This is why the standard 'sequence' for systems supporting autochanging, is the sending of a single character (like 0x13), and a gap repeatedly. This allows the receiving system to change rates, and resynchronise to the new rate.
Best Wishes |
|
|
Anna
Joined: 29 Dec 2003 Posts: 4
|
FERR error |
Posted: Mon Mar 08, 2004 1:59 am |
|
|
Thank you for answer, Ttelmah,
If I catch FERR or OERR then :
while (RCSTA & 0x06)
{
disable_interrupts(INT_RDA);
disable_interrupts(GLOBAL);
RCSTA = 0x80;
ch = RCREG;
ch = RCREG;
ch = RCREG;
RCSTA = 0x90;
X_Rx_Init(); // reinit USART
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
}
Problem is RCSTA = 0x80 - clear error, I am failed on write 0x80 to RCSTA, because error occur again... and all lines below not work.Only reset of controller helps - in reset I do reinit USART in same way. _________________ Anna |
|
|
Ttelmah Guest
|
Re: FERR error |
Posted: Mon Mar 08, 2004 4:52 am |
|
|
Anna wrote: | Thank you for answer, Ttelmah,
If I catch FERR or OERR then :
while (RCSTA & 0x06)
{
disable_interrupts(INT_RDA);
disable_interrupts(GLOBAL);
RCSTA = 0x80;
ch = RCREG;
ch = RCREG;
ch = RCREG;
RCSTA = 0x90;
X_Rx_Init(); // reinit USART
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
}
Problem is RCSTA = 0x80 - clear error, I am failed on write 0x80 to RCSTA, because error occur again... and all lines below not work.Only reset of controller helps - in reset I do reinit USART in same way. |
Do it differently:
Code: |
#bit OERR=RCSTA.1
#bit FERR=RCSTA.2
#bit CREN=RCSTA.4
while (RCSTA & 0x06) {
{
ch=RCREG;
if (OERR) {
CREN=0;
CREN=1;
}
}
|
If you are using INT_RDA, this should be _inside_ the receive interrupt handler. The chip will develop an interrupt for the error.
You do not need/want to fully re-initialise the UART for the error condition.
However you do want to disable continuous read, and re-enable it to clear OERR.
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
|