View previous topic :: View next topic |
Author |
Message |
ciccioc74
Joined: 23 Mar 2010 Posts: 30
|
5 usart used simultaneously |
Posted: Tue Feb 09, 2021 11:39 am |
|
|
Hi everyone
pic PIC24FJ1024GB610
xtal 8MHz clock = 32M
usart @ 9600 baud
I should receive data (byte array of variable size max 30 bytes) arriving on 4 serial asynchronously.
Each slave peripheral transmits approximately every 30mS.
The problem is that if 2 or more data arrive at the same time, the system does not respond correctly.
The prototype of definition:
Code: | #use rs232(UART1, baud=9600, stream=UART_1,ERRORS) |
IRQ from receive
Code: | #INT_RDA//interrupt da seriale n 1
void rda_isr(void){
datiTX_1[0][contaDati_1]=fgetc(UART_1);
[...]
}
#INT_RDA2//interrupt da seriale n 2
void rda_isr2(void){
datiTX_2[0][contaDati_2]=fgetc(UART_2);
[...]
}
|
The data is stored in an array until a marker arrives (this works well) as soon as the array is complete I transmit it on the UART6
into the while(1):
Code: |
if(DatoInArrivo_1 ){//mark for data ready
datiTX_1[0]=0XAA;
datiTX_1[1]=0X55;
datiTX_1[2]=tasto_1;
fputc(datiTX_1[0],UART_6);//inizio trasmissione
}
if(DatoInArrivo_2 ){//mark for data ready
send data2
|
This for each of 4 serial.
Can you confirm that the serial ports work independently? Should i use DMA to not engage the micro or is it not needed?
I have a plan "b" which is to make the transmission synchronized by the master but i would not use it.
Last edited by ciccioc74 on Tue Feb 09, 2021 12:22 pm; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Tue Feb 09, 2021 12:05 pm |
|
|
You should be happily able to receive from all four serials.
You do realise that there needs to be four separate ISR's for the four
ports and each needs to receive from the separate stream.
How do your ISR's handle incrementing the location they store to? You don't
show this or how it wraps.
Yes, the ports do work independently. However the ISR should keep
reading so long as data is available. This is different for the PIC24/30
versus the PIC18, because of the large buffers in these chips. |
|
|
ciccioc74
Joined: 23 Mar 2010 Posts: 30
|
|
Posted: Tue Feb 09, 2021 12:19 pm |
|
|
Thanks for the quick response.
The data of each serial are stored in 4 simple arrays sufficiently large until I receive the MARK. (usart1 array1, usart2 array2 etc) once the array is completed I send it to serial n 6.
Can you confirm that if the data arrives at the same time (sometimes it could happen) the arrays fill up independently? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Tue Feb 09, 2021 12:36 pm |
|
|
Yes, provided as I say, each ISR loops while data is available. The point
is that on these chips you have several bytes of buffering for each
UART, so the ISR has to be built to loop while there is data in this buffer. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Wed Feb 10, 2021 2:47 am |
|
|
OK.
Now first thing, your post shows you setting up UART1, but then shows
the receive for UART2.
Correct sequence, needs to be, ##pin_select for each UART (where the
pins are not fixed), then a #USE for each UART. Unique names for each.
Then #INT_RDAx for each enabled UART, like:
Code: |
#INT_RDA2
void rda2_isr(void)
{
do
{
datiTX_2[0][contaDati_2]=fgetc(UART_2);
//whatever code you do to update ContaDati
//You should also make sure that this value cannot overflow.
//remember you may get more data than you expect, and the routine
//has to carry on dealing with this while your main code is
//processing. Handling of this is _[u]critical[/u]_.
} while (kbhit(UART_2));
}
|
The point is that unlike the PIC18, where if two bytes are sitting in the
hardware buffer, and you interrupt, if a second byte is waiting the
interrupt will be called again. On the PIC24, it won't. If there were two bytes
in the buffer when the interrupt was called, and you exit, the interrupt
flag will not be set again till another byte arrives. If you then only handle
one byte, gradually the hardware buffer will fill up with unhandled
characters..... |
|
|
ciccioc74
Joined: 23 Mar 2010 Posts: 30
|
|
Posted: Wed Feb 10, 2021 4:13 am |
|
|
ok I do the test |
|
|
ciccioc74
Joined: 23 Mar 2010 Posts: 30
|
|
Posted: Wed Feb 10, 2021 7:11 am |
|
|
Ok. I confirm that it manages the reception of data from 5 UARTs at the same time. The problem was sw on a variable inside the IRQ routine not declared "static".
Thanks for the support. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Wed Feb 10, 2021 7:32 am |
|
|
As a further comment to this, 'using DMA', is great if you are sending fixed
size packets, and/or receiving packets that always arrive in fixed sizes.
However it is not the way to go if things have variable sizes, or if flow
control is involved.
If you are sending (say) 16byte packets and no flow control is needed,
then using DMA can save a lot of processor time. However if the transmission
may need to pause for flow control or may have variable sizes, then forget
using DMA. |
|
|
|