View previous topic :: View next topic |
Author |
Message |
Mrinmoy
Joined: 20 Dec 2023 Posts: 15
|
PIC24F Series uart problem |
Posted: Sat Aug 10, 2024 6:05 am |
|
|
Hi,
I am using PIC24FJ512GL406 in one of my project where my ccs version is 5.101.
In that project I am taking data from camera to microcontroller using RS232. I am facing a issue of receiving partial data from camera over the UART where the data length is 14 digits. I have cross-check the situation in many ways when the camera sending the same data to other serial monitor. But whenever it connects to the microcontroller it happens for sometime and then automatically recovers.
Is there anything that happens with hardware buffer that may create problem or is there anything to set from software.
My set clock speed is 32MHz and baud rate tested at 9600 to 115200.
Any help regarding this will be highly appreciated.
Thanks in advance . |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Sat Aug 10, 2024 6:19 am |
|
|
HOW are you coding for the serial data ?
Normally you'll use an ISR and buffer, check the CCS example 'ex_sisr.c' !
You'll also have to add 'ERRORS' to the #USE RS232 ( ...options....). Without that , the PIC 'freezes' do to overrun.
Posting a small program will help us see what could be the problem ! Others with '24' experience can then compile and test your code on their computers. |
|
|
Mrinmoy
Joined: 20 Dec 2023 Posts: 15
|
|
Posted: Sat Aug 10, 2024 6:36 am |
|
|
@temtronic
Yes, I am using ISR for rceiving data and ERRORS in #use rs232. Here are some parts of my code
Code: |
//// ############### Configure UART1 -> Using for MCU -> CAMERA ########
#PIN_SELECT U1RX=PIN_C14
#PIN_SELECT U1TX=PIN_D0
#use rs232(UART1, baud=115200, ERRORS, stream=CAMERA)
#INT_RDA
void rda_isr(void)
{
g_ui8RS232CurrByte = fgetc(CAMERA);
// Receive buffer.
g_ui8ArrCameraRcvBuffer[g_ui8CamRcvByteCount] = g_ui8RS232CurrByte;
// Increment receive byte count.
g_ui8CamRcvByteCount++;
// Check the delimeter.
if(g_ui8RS232PrevByte == CR &&
g_ui8RS232CurrByte == LF)
{
g_fBarcodeStatus = TOTAL_BARCODE_RECEIVED;
}
g_ui8RS232PrevByte = g_ui8RS232CurrByte;
// Check with buffer size.
if(g_ui8CamRcvByteCount >= SIZE_CAM_RCV_BUFF)
{
// Reset byte count.
g_ui8CamRcvByteCount = 0;
g_ui8CAMBufferStatus = BUFFER_FULL;
}
// Clear interrupt.
clear_interrupt(INT_RDA);
}
|
|
|
|
Mrinmoy
Joined: 20 Dec 2023 Posts: 15
|
|
Posted: Sat Aug 10, 2024 8:31 am |
|
|
I found some points from ccs help but need some illustration.
1. Use of ERROR in #use re232.
2. Use of RECEIVE_BUFFER in options of #use rs232
It will be very helpful if someone give some explanation of above points and is there any relation of those with my proble. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1351
|
|
Posted: Sat Aug 10, 2024 9:51 am |
|
|
A few things to consider:
1. Don't clear the interrupt at the end. CCS handles that automatically unless you tell it not to (which you aren't, so just let it handle it).
2. If your buffer size is too small, then checking CR and LF like you are in the ISR can lead to situations where earlier message data is deleted before you can fully process the message in the main. Make sure your buffer size is 2-3 times larger than the max camera message size and that your main code doesn't take too long to actually copy the message from the ISR buffer.
3. PIC24's often have a 4 byte receive hardware buffer.. I would recommend putting your ISR code inside a while(kbhit()) loop:
Code: |
#INT_RDA
void rda_isr(void)
{
while(kbhit(CAMERA)){
//your ISR stuff here
}
}
|
Last edited by jeremiah on Sat Aug 10, 2024 6:12 pm; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Sat Aug 10, 2024 1:42 pm |
|
|
As a further comment ERRORS does not function on the PIC24's etc..
The error bits are actually stored with the bytes. You read the byte and
the error bits are available in the RS232_ERRORS byte. You must read
multiple bytes in the receive interrupt, If you want to handle errors, use
an error interrupt, and in this just read the byte, and process the error. |
|
|
Mrinmoy
Joined: 20 Dec 2023 Posts: 15
|
|
Posted: Sat Aug 10, 2024 10:36 pm |
|
|
@Ttelmah thank you for your comments. It helps me to understand the situation little bit. But if ERRORS doesn't work for 24Fs series then uart will recover if they hang? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Sun Aug 11, 2024 12:16 am |
|
|
The key point is the one Jeremiah made. Unlike the PIC18's, the PIC24's
will not retrigger an interrupt if you exit with another byte waiting.
Combine this with the much larger buffer, and the interrupt must read
all the bytes in the buffer before exiting. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Sun Aug 11, 2024 7:32 am |
|
|
The really smart way to handle errors is to use the interrupt:
Code: |
//after the processor include:
#device NESTED_INTERRUPTS=TRUE
//For all the UART's you use.
#word U1STA=getenv("SFR:U1STA")
#word U2STA=getenv("SFR:U2STA")
#word U3STA=getenv("SFR:U3STA")
#word U4STA=getenv("SFR:U4STA")
#bit OERR1=U1STA.1
#bit FERR1=U1STA.2
#bit PERR1=U1STA.3
#bit OERR2=U2STA.1
#bit FERR2=U2STA.2
#bit PERR2=U2STA.3
#bit OERR3=U3STA.1
#bit FERR3=U3STA.2
#bit PERR3=U3STA.3
#bit OERR4=U4STA.1
#bit FERR4=U4STA.2
#bit PERR4=U4STA.3
#word U1RXREG=getenv("SFR:U1RXREG")
#word U2RXREG=getenv("SFR:U2RXREG")
#word U3RXREG=getenv("SFR:U3RXREG")
#word U4RXREG=getenv("SFR:U4RXREG")
#define CAT(name,val) name##val
#define CAT3(x,y,z) x##y##z
#define EFUNCTION(x) void CAT(errorint, x) (void) { \
static int16 eword; \
if (CAT(OERR,x)) { CAT(OERR,x) = 0; return; } \
if (CAT(PERR,x)) { eword=CAT3(U,x,RXREG); } \
if (CAT(FERR,x)) { eword=CAT3(U,x,RXREG); } \
}
//Then for each UART in use:
#INT_UART1E LEVEL=5
EFUNCTION(1)
//For UART2 etc..
#INT_UART2E LEVEL=5
EFUNCTION(2)
|
You can copy the word variable into something to use if you want. This is
the received byte that had the error..
The parity error and framing error both clear by reading the byte. The
overrun error simply has the bit cleared. The functions generated are
higher priority than the standard interrupts, so the error is handled
before the receive handlers are called.
For my use I throw any byte with errors. |
|
|
Mrinmoy
Joined: 20 Dec 2023 Posts: 15
|
|
Posted: Wed Aug 21, 2024 9:11 am |
|
|
@Ttelmah
Thank you for your valuable help and clearly written words that help me to understand my mistakes.
Actually I treat PIC24s UART same as PIC18s where I made the main mistake where use of kbhit take care of it.
Thank you again. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Wed Aug 21, 2024 9:17 am |
|
|
Good. That was the critical one. On the PIC 16/18, if you exit the interrupt,
you will automatically get another interrupt if a byte is waiting. On the
16 bit PIC's this isn't the case, Hence always vital to test if more bytes
are waiting. |
|
|
|