Hi,
I have problem when recieving UART data using Interrupt. I use EasyPIC Fusion V7 and PIC32MX795F512L.
Everything works well when I sending 8 or less caraters to board. When I try to send more then 8 ISR doesn't worke anymore.
I attached all project files in zip.
Does anyone have some suggestion how to solve this problem.
Thank you.
BR,
Ivo
UART Interrupt problem
-
- Posts: 54
- Joined: 20 Oct 2014 12:33
UART Interrupt problem
- Attachments
-
- Uart_Demo.zip
- (423.63 KiB) Downloaded 124 times
Last edited by ikrajinovic on 16 May 2018 12:46, edited 2 times in total.
Re: UART Interrupt problem
The idea of using interrupts for UART receive is that your interrupt routine puts all received characters into a buffer, updates the buffer pointer(s) and gets out of the interrupt routine as fast as possible.
Your "main" loop should then handle the receive buffer at leisure, in the safe knowledge that interrupts will handle receive data as fast as it is sent.
You are spending far too much time processing each interrupt, so that incoming serial data is no longer being processed. There is only a 4 byte hardware buffer (IIRC) so there is limited hardware buffering.
As a terrible cludge, you could change UART5_Write_Text("---UART while: "); to UART5_Write_Text(":");
This may allow a few more bytes to be sent consecutively before disaster happens, but this would be a bodge, not a solution.
In summary: Use receive interrupts to fill a buffer of sufficient size for your application and do processing within main loop. Avoid intensive or slow processing within your interrupt routine.
Your "main" loop should then handle the receive buffer at leisure, in the safe knowledge that interrupts will handle receive data as fast as it is sent.
You are spending far too much time processing each interrupt, so that incoming serial data is no longer being processed. There is only a 4 byte hardware buffer (IIRC) so there is limited hardware buffering.
As a terrible cludge, you could change UART5_Write_Text("---UART while: "); to UART5_Write_Text(":");
This may allow a few more bytes to be sent consecutively before disaster happens, but this would be a bodge, not a solution.
In summary: Use receive interrupts to fill a buffer of sufficient size for your application and do processing within main loop. Avoid intensive or slow processing within your interrupt routine.
Start every day with a smile...... (get it over with)
-
- Posts: 54
- Joined: 20 Oct 2014 12:33
Re: UART Interrupt problem
Thank you.
Your suggestion solved my problem. I short ISR and everything works OK.
This is how it looks now:
Your suggestion solved my problem. I short ISR and everything works OK.
This is how it looks now:
Code: Select all
void UART5interrupt() iv IVT_UART_5 ilevel 6 ics ICS_AUTO {
while(UART5_Data_Ready())
{
uart_rd = UART5_Read(); // read the received data
txt[dataCounter] = uart_rd;
dataCounter++;
}
if (dataCounter == 128)
{
dataCounter = 0;
}
dataFlag = 1;
U5RXIF_bit = 0;
}
-
- Posts: 54
- Joined: 20 Oct 2014 12:33
Re: UART Interrupt problem
I have one more problem about reading UART data.
Everything works extremely well when i declare where BUFLEN is less than 255. But when I try to increase array length I have a program that is not working after first message arrived that is longer than 255 bytes. I declare constant for array length.
This is my ISR:
I main I have this:
Everything works extremely well when i declare
Code: Select all
volatile char txt[BUFLEN + 1];
Code: Select all
const unsigned int BUFLEN = 256;
Code: Select all
void UART5interrupt() iv IVT_UART_5 ilevel 6 ics ICS_AUTO {
while(UART5_Data_Ready() == 1)
{
uart_rd = UART5_Read(); // read the received data
if(dataCounter < BUFLEN)
{
txt[dataCounter] = uart_rd;
dataCounter++;
}
}
dataFlag = 1;
U5RXIF_bit = 0;
}
Code: Select all
while(1)
{
if (dataFlag == 1 && UART5_Data_Ready() == 0){
dataFlag = 0;
txt[dataCounter] = '\0';
if(dataCounter > 0)
{
UART5_Write_Text(txt);
UART5_Write(13);
UART5_Write(10);
}
else
{
UART5_Write_Text("Buffer is empty");
UART5_Write(13);
UART5_Write(10);
}
dataCounter = 0;
memset( txt, 0, (BUFLEN+1));
}
}
Re: UART Interrupt problem - Solved
Did you change declaration of dataCounter from unsigned short (0 to 255) to unsigned int (0 to 65535)?
Start every day with a smile...... (get it over with)
-
- Posts: 54
- Joined: 20 Oct 2014 12:33
Re: UART Interrupt problem
Yes. Now it is
Code: Select all
volatile unsigned int dataCounter = 0;
-
- Posts: 54
- Joined: 20 Oct 2014 12:33
Re: UART Interrupt problem
The problem was in library function UARTx_Write_Text.
This function was unable to send string longer than 255 caracters.
I made custom function and now everything works great.
This function was unable to send string longer than 255 caracters.
I made custom function and now everything works great.
Code: Select all
void UART5_Write_String(const char* str) {
int i = 0;
for (i = 0 ; str[i]!='\0' ; i++) {
UART5_Write(str[i]);
}
}
Re: UART Interrupt problem
I encountered the UARTx_Write_Text 255 charater limit in mikrobasic too.
In the help file it doesn't specify a limit to the amount of characters you can sent trough UARTx_Write_Text.
I had to make my own function as well in order to sent a larger buffer trough UART, actually checking for the null at the end of the string rather than using a loop variable.
In the help file it doesn't specify a limit to the amount of characters you can sent trough UARTx_Write_Text.
I had to make my own function as well in order to sent a larger buffer trough UART, actually checking for the null at the end of the string rather than using a loop variable.
Just tell me....