|
|
View previous topic :: View next topic |
Author |
Message |
[email protected]
Joined: 28 Jul 2014 Posts: 38
|
Overrun error oerr in uart |
Posted: Sat Jun 06, 2020 1:08 pm |
|
|
I am using dsPic33ep512mu810. In that i am getting overrun error.
For example:
There are 2 while loops. In the first loop if i get 9 'A', then it will break and come to the second loop.
If i send 9 'A' THROUGH DOCKLIGHT SOFTWARE it is working correctly.
If i put the delay_ms(500); then i am getting oerr error.
Code: |
while(true) /// first loop
{
delay_ms(500); /// if this added oerr error coming
if(uart_available_uart1())
{
x = uart_read_uart1();
if(x=='A')
{
COUNT_3=COUNT_3+1;
}
}
IF(COUNT_3==9)
{
BREAK;
}
}
WHILE(TRUE)// second loop
{
DELAY_MS(100);
OUTPUT_TOGGLE(PIN_B7);
lcd_gotoxy (2, 1);
printf (lcd_putc2, "%04lu",COUNT_3);
}
#word U1STA = 0x0222
#bit U1_OERR = U1STA.1
#bit U1_URXDA= U1STA.0 /// RECIVER BUFFER STATUS
#define SERIAL_BUFFER_SIZE 512
#INT_RDA
void RDA1_isr(void)
{
store_char_uart1(fgetc(UART_PORT1));
if(U1_OERR) // If over run error, then reset the receiver
{
COUNT_2=COUNT_2+1;
uart_flush_uart1();
alaram_vib(2);
lcd_gotoxy (3, 1);
printf (lcd_putc3, "%04lu",count_2);
U1_OERR = 0;
}
}
void uart_init_1()
{
rx_buffer_Uart1.head = 0;
rx_buffer_Uart1.tail = 0;
if(U1_OERR) {
U1_OERR = 0;
}
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
uart_flush_uart1();
}
|
|
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sat Jun 06, 2020 6:07 pm |
|
|
That's really not how you want to write that.
First -- IRQ based RS232 == Good.
But keep it simple. No printf in your INT_RDA routine.
Avoid jumping to subroutines in the ISR. Keep everything right there if you can.
You should be
* snagging the char,
* stuffing into a buffer,
* doing buffer management.
Any other cleanup like
* setting received char flags or maybe a count or pointers if you have a ring buffer
* clearing the IRQ flag (if needed - depends on the PIC.)
In your main loop, you don't use a delay. write your main loop to free run and if there's a change in RS232 RX buffer status, then do something about it.
Let your main loop run as fast as it can.
Also, I don't know why you have a call to read the UART from MAIN and an IRQ which is where you should be getting any data from the UART. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Jun 07, 2020 12:54 am |
|
|
and be aware, you can't just clear the OERR bit. You have to read the
data from the UART buffer before this bit will clear. Your clear in the main
won't work.
Generally, having any routine inside the interrupt and outside, will result
in the warning 'Interrupt disabled to prevent re-entrancy', and mean that
interrupts won't be called while you are in the 'main' version of the
routine. Not the way to work. You don't show us what is in
uart_flush_uart1 or alaram_vib
I's guess that one of these actually contains a delay. Result interrupts
are disabled for the delay out in the main code, and an automatic overrun...
General rules are:
1) Have interrupt handlers _only_ do the job that the interrupt signals
needs to be done. Keep them as short and quick as possible.
2) If complex jobs need to be done based on what has happened, set a
flag and do this out in the main code.
3) Avoid anything involving delays in interrupts (break this only with
short 'delay_cycle' type delays required to synchronise with hardware).
4) Avoid calling anything both inside the interrupt and in the main code.
If a serial is handled by the interrupt, all it's operations should be done
using the interrupt.
Also, change the interrupt like:
Code: |
while (kbhit(UART_PORT1))
store_char_uart1(fgetc(UART_PORT1));
|
On the PIC16/18, the INT_RDA will re-trigger if there is a second
character received, and the internal buffer is just one character. On the
DsPIC's the UART hardware buffer is much larger, and the interrupt will
not re-trigger until another character is received. If there are multiple
characters waiting in the hardware buffer, these all need to be read. |
|
|
|
|
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
|