|
|
View previous topic :: View next topic |
Author |
Message |
diogodpg1
Joined: 19 Jun 2022 Posts: 7
|
problem to receive uart message correctly |
Posted: Sun Jun 19, 2022 7:24 am |
|
|
hi.
I am trying to receive uart data from a Nextion display.
I am new to this so i search forums and datasheet, made a lot of codes and this is the best i got so far:
Code: |
#include <teste3.h>
unsigned char buffer[5];
unsigned short idx;
char flagrx=0;
char dummy=0;
char c;
#byte DADOS_REC_NEX = getenv("sfr:U4RXREG")
#BIT BUFF = getenv("bit:U4RXIF")
#BIT FRAM = getenv("bit:U4STA.FERR")
#BIT OVER = getenv("bit:U4STA.OERR")
#BIT PAR = getenv("bit:U4STA.PERR")
//#BIT PRONTO = getenv("bit:U4STA.URXISEL")
void processarx()
{
output_bit(PIN_D2, TRUE);
if (flagrx==1)
{
fprintf(NEXTION,"Inicial.t3.txt=\"recbendo\"\xFF\xFF\xFF");
output_bit(PIN_D4, TRUE);
c = DADOS_REC_NEX;//getc(NEXTION);
buffer[idx] = c;
idx++;
fprintf(NEXTION,"Inicial.t1.txt=\"%u\"\xFF\xFF\xFF",c);
FRAM=0;
OVER=0;
PAR=0;
enable_interrupts(INT_RDA4);
fprintf(NEXTION,"Inicial.t5.txt=\"%u\"\xFF\xFF\xFF",idx);
fprintf(NEXTION,"Inicial.t3.txt=\"cocluido\"\xFF\xFF\xFF");
if (idx==6) {flagrx=0;}
output_bit(PIN_D4, FALSE);
}
output_bit(PIN_D2, TRUE);
}
#INT_RDA4
void rda_isr(void)
{
flagrx=1;
}
void main()
{
delay_ms(500);
enable_interrupts(INT_RDA4);
enable_interrupts(INT_RDA);
enable_interrupts(INTR_GLOBAL);
dummy = DADOS_REC_NEX;
buffer[0]=0;
buffer[1]=0;
buffer[2]=0;
buffer[3]=0;
buffer[4]=0;
buffer[5]=0;
idx=0;
while(TRUE)
{
fprintf(NEXTION,"Inicial.t7.txt=\"%u\"\xFF\xFF\xFF",buffer[0]);
fprintf(NEXTION,"Inicial.t9.txt=\"%u\"\xFF\xFF\xFF",buffer[1]);
fprintf(NEXTION,"Inicial.t11.txt=\"%u\"\xFF\xFF\xFF",buffer[2]);
fprintf(NEXTION,"Inicial.t13.txt=\"%u\"\xFF\xFF\xFF",buffer[3]);
fprintf(NEXTION,"Inicial.t15.txt=\"%u\"\xFF\xFF\xFF",buffer[4]);
fprintf(NEXTION,"Inicial.t17.txt=\"%u\"\xFF\xFF\xFF",buffer[5]);
processarx();
OUTPUT_BIT(PIN_D3, TRUE);
delay_ms(500);
OUTPUT_BIT(PIN_D3, FALSE);
delay_ms(500);
}
}
|
The fprintf and leds are to watch the behavior until i make it work properly.
I receive the data from the Nextion and send to buffer[].
The problem is that the idx keeps counting up, not just when it has an interrupt, so the data received is stored in wrong places in buffer[]
when idx==6 goes to start counting again.
I already try different ways but end up with idx=1 and not counting.
If I make idx=sum+1 instead idx++ the idx stays at 1, and only a part of the data is received.
I appreciate any suggestions.
I am using ccs 5.00
dspic33ep512mu810
Nextion nx8048p070_011
Pickit3
thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Sun Jun 19, 2022 7:47 am |
|
|
Key problem.
The INT_RDA routine _MUST_ read the received character.
The interrupt will remain set, until this is done. Result the processor
will loop and call the routine again (and again, and again...). The code
will efectively stall at this point.
Look at ex_sisr.c
This shows a basic serial receive ISR. |
|
|
diogodpg1
Joined: 19 Jun 2022 Posts: 7
|
|
Posted: Sun Jun 19, 2022 8:03 am |
|
|
Thanks Ttelmah for answer.
I have tested with the read receive character in the INT_RDA and the idx stays in 1, and didn't receive all the message.
this:
Code: |
#INT_RDA4
void rda_isr(void)
{
c = DADOS_REC_NEX; //getc(NEXTION);
buffer[idx] = c;
idx++;
if (idx==6)
{
flagrx=1;
}
}
|
Also try to include a BUFF=0; at the end but idx stay in 1 and don't receive full message.
Thanks for suggestions. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Sun Jun 19, 2022 8:18 am |
|
|
possibly this ??
enable_interrupts(INT_RDA4);
enable_interrupts(INT_RDA);
enable_interrupts(INTR_GLOBAL);
you enable TWO interrupts, but only have a 'handler'(ISR code) for _RDA4. |
|
|
diogodpg1
Joined: 19 Jun 2022 Posts: 7
|
|
Posted: Sun Jun 19, 2022 8:22 am |
|
|
temtronic thanks for answer.
going to remove and try.
thanks
Ttelmah, i am reading ex_sisr, going to make some changes and try also.
thanks |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 479 Location: Montenegro
|
|
Posted: Sun Jun 19, 2022 8:44 am |
|
|
Read the incoming character in RDA_ISR with:
Code: | c=getc(); // get received char and with that also clear interrupt flag
|
Quote: |
c = DADOS_REC_NEX;//getc(NEXTION);
|
I don't know if this does the reading |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 479 Location: Montenegro
|
|
Posted: Sun Jun 19, 2022 8:53 am |
|
|
Also after you get to idx = 6 you gave to reset it back to 0, otherwise it will just count on.
Code: |
#INT_RDA4
void rda_isr(void)
{
c = getc(); // read char, clear interrupt flag
buffer[idx] = c;
idx++;
if (idx==6)
{
idx = 0; // reset counter
flagrx=1;
}
}
|
|
|
|
diogodpg1
Joined: 19 Jun 2022 Posts: 7
|
|
Posted: Sun Jun 19, 2022 9:20 am |
|
|
PrinceNai, thanks for answer.
I included that.
thanks for all the help so far. now works almost correctly.
the code this now:
Code: |
#include <teste3.h>
unsigned char buffer[5];
unsigned short idx;
char flagrx=0;
char dummy=0;
char c;
char dados;
#byte DADOS_REC_NEX = getenv("sfr:U4RXREG")
#BIT BUFF = getenv("bit:U4RXIF")
#BIT FRAM = getenv("bit:U4STA.FERR")
#BIT OVER = getenv("bit:U4STA.OERR")
#BIT PAR = getenv("bit:U4STA.PERR")
//#BIT PRONTO = getenv("bit:U4STA.URXISEL")
void processarx()
{
output_bit(PIN_D2, TRUE);
if (flagrx==1)
{
fprintf(NEXTION,"Inicial.t3.txt=\"recbendo\"\xFF\xFF\xFF");
output_bit(PIN_D4, TRUE);
fprintf(NEXTION,"Inicial.t1.txt=\"%u\"\xFF\xFF\xFF",c);
dados = buffer[3];
FRAM=0;
OVER=0;
PAR=0;
enable_interrupts(INT_RDA4);
fprintf(NEXTION,"Inicial.t5.txt=\"%u\"\xFF\xFF\xFF",idx);
fprintf(NEXTION,"Inicial.t3.txt=\"cocluido\"\xFF\xFF\xFF");
// if (idx==6) {flagrx=0;}
flagrx=0;
output_bit(PIN_D4, FALSE);
idx=0;
memset(buffer,0,5);
}
output_bit(PIN_D2, FALSE);
}
#INT_RDA4
void rda_isr(void)
{
c = DADOS_REC_NEX;//getc(NEXTION);
buffer[idx] = c;
idx++;
if (idx==4)
{
flagrx=1;
BUFF=0;
}
}
void main()
{
delay_ms(500);
enable_interrupts(INT_RDA4);
// enable_interrupts(INT_RDA);
enable_interrupts(INTR_GLOBAL);
dummy = DADOS_REC_NEX;
buffer[0]=0;
buffer[1]=0;
buffer[2]=0;
buffer[3]=0;
buffer[4]=0;
buffer[5]=0;
idx=0;
while(TRUE)
{
fprintf(NEXTION,"Inicial.t7.txt=\"%u\"\xFF\xFF\xFF",buffer[0]);
fprintf(NEXTION,"Inicial.t9.txt=\"%u\"\xFF\xFF\xFF",buffer[1]);
fprintf(NEXTION,"Inicial.t11.txt=\"%u\"\xFF\xFF\xFF",buffer[2]);
fprintf(NEXTION,"Inicial.t13.txt=\"%u\"\xFF\xFF\xFF",buffer[3]);
fprintf(NEXTION,"Inicial.t15.txt=\"%u\"\xFF\xFF\xFF",buffer[4]);
fprintf(NEXTION,"Inicial.t17.txt=\"%u\"\xFF\xFF\xFF",dados);
processarx();
OUTPUT_BIT(PIN_D3, TRUE);
delay_ms(500);
OUTPUT_BIT(PIN_D3, FALSE);
delay_ms(500);
}
}
|
now i receive the message one time correct and the other not.
the nextion program has a button to sum a number and send to pic.
it should send like this:
01 01 01 255 255 255
01 01 02 255 255 255
01 01 03 255 255 255
01 01 04 255 255 255
01 01 05 255 255 255
i am receiving the 01 01 01, 01 01 03, 01 01 05 correctly. The others looks like more data came and is messing with.
thanks for suggestions. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 479 Location: Montenegro
|
|
Posted: Sun Jun 19, 2022 9:29 am |
|
|
You changed idx from 5 max to 3 max and if I'm not mistaken, you are still not clearing it after you get your message. |
|
|
diogodpg1
Joined: 19 Jun 2022 Posts: 7
|
|
Posted: Sun Jun 19, 2022 9:38 am |
|
|
PrinceNai, thanks for answer.
i changed to test, with 5 have the same problem.
i put BUFF=0 to clear. This is not correct?
#BIT BUFF = getenv("bit:U4RXIF")
thanks for help |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 479 Location: Montenegro
|
|
Posted: Sun Jun 19, 2022 9:48 am |
|
|
I really don't know, I'd never do it that way. Why using two names for the same thing? Does BUFF=0 clear idx? The way I understand it, it clears the interrupt flag. My guess would be you are staying inside the interrupt, receive four characters, THEN clear the interrupt flag and exit to main. The way I posted earlier works 100%, without any #getenv. CCS does it all for you. |
|
|
diogodpg1
Joined: 19 Jun 2022 Posts: 7
|
|
Posted: Sun Jun 19, 2022 10:54 am |
|
|
PrinceNai wrote: | I really don't know, I'd never do it that way. Why using two names for the same thing? Does BUFF=0 clear idx? The way I understand it, it clears the interrupt flag. My guess would be you are staying inside the interrupt, receive four characters, THEN clear the interrupt flag and exit to main. The way I posted earlier works 100%, without any #getenv. CCS does it all for you. |
PrinceNai, thanks for the answer.
BUFF=0 is to clear the interrupt. I included to try clear the interrupt, without it works the same way.
Going to change to getc and try again, without the BUFF.
thanks again. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 479 Location: Montenegro
|
|
Posted: Sun Jun 19, 2022 11:40 am |
|
|
Interrupt must be cleared after every character. That is what getc() does automatically. idx must be cleared so that the message goes to the correct places in the buffer.
One other thing to mention. The data from display is probably terminated in some way, be it NULL, line feed, carriage return or some combination of those. With the current setup those are going to finish in the buffer, causing problems. |
|
|
diogodpg1
Joined: 19 Jun 2022 Posts: 7
|
|
Posted: Sun Jun 19, 2022 1:35 pm |
|
|
PrinceNai, thanks for the help.
With getc() and the correct buffer size all working now.
Also thanks to Ttelmah and temtronic for the help.
Here is the final code:
Code: |
#include <teste3.h>
unsigned char buffer[3];
unsigned short idx;
char flagrx=0;
char dummy=0;
char c;
char dados;
#byte DADOS_REC_NEX = getenv("sfr:U4RXREG")
#BIT BUFF = getenv("bit:U4RXIF")
#BIT FRAM = getenv("bit:U4STA.FERR")
#BIT OVER = getenv("bit:U4STA.OERR")
#BIT PAR = getenv("bit:U4STA.PERR")
//#BIT PRONTO = getenv("bit:U4STA.URXISEL")
void processarx()
{
output_bit(PIN_D2, TRUE);
if (flagrx==1)
{
fprintf(NEXTION,"Inicial.t3.txt=\"recbendo\"\xFF\xFF\xFF");
output_bit(PIN_D4, TRUE);
fprintf(NEXTION,"Inicial.t1.txt=\"%u\"\xFF\xFF\xFF",c);
dados = buffer[2];
FRAM=0;
OVER=0;
PAR=0;
enable_interrupts(INT_RDA4);
fprintf(NEXTION,"Inicial.t3.txt=\"cocluido\"\xFF\xFF\xFF");
// if (idx==6) {flagrx=0;}
flagrx=0;
output_bit(PIN_D4, FALSE);
idx=0;
memset(buffer,0,3);
}
output_bit(PIN_D2, FALSE);
}
#INT_RDA4
void rda_isr(void)
{
c = getc(NEXTION);//DADOS_REC_NEX;
buffer[idx] = c;
idx++;
if (idx>2)
{
flagrx=1;
}
}
void main()
{
delay_ms(500);
enable_interrupts(INT_RDA4);
// enable_interrupts(INT_RDA);
enable_interrupts(INTR_GLOBAL);
dummy = DADOS_REC_NEX;
buffer[0]=0;
buffer[1]=0;
buffer[2]=0;
// buffer[3]=0;
// buffer[4]=0;
// buffer[5]=0;
idx=0;
while(TRUE)
{
fprintf(NEXTION,"Inicial.t7.txt=\"%u\"\xFF\xFF\xFF",buffer[0]);
fprintf(NEXTION,"Inicial.t9.txt=\"%u\"\xFF\xFF\xFF",buffer[1]);
fprintf(NEXTION,"Inicial.t11.txt=\"%u\"\xFF\xFF\xFF",buffer[2]);
fprintf(NEXTION,"Inicial.t13.txt=\"%u\"\xFF\xFF\xFF",buffer[3]);
fprintf(NEXTION,"Inicial.t15.txt=\"%u\"\xFF\xFF\xFF",buffer[4]);
fprintf(NEXTION,"Inicial.t17.txt=\"%u\"\xFF\xFF\xFF",dados);
processarx();
fprintf(NEXTION,"Inicial.t5.txt=\"%u\"\xFF\xFF\xFF",idx);
OUTPUT_BIT(PIN_D3, TRUE);
delay_ms(500);
OUTPUT_BIT(PIN_D3, FALSE);
delay_ms(500);
}
}
|
thans to all. |
|
|
|
|
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
|