CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

problem to receive uart message correctly

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
diogodpg1



Joined: 19 Jun 2022
Posts: 7

View user's profile Send private message

problem to receive uart message correctly
PostPosted: Sun Jun 19, 2022 7:24 am     Reply with quote

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: 18072

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 7:47 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 8:03 am     Reply with quote

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: 8525
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 8:18 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 8:22 am     Reply with quote

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: 327
Location: Montenegro

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 8:44 am     Reply with quote

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: 327
Location: Montenegro

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 8:53 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 9:20 am     Reply with quote

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: 327
Location: Montenegro

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 9:29 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 9:38 am     Reply with quote

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: 327
Location: Montenegro

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 9:48 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 10:54 am     Reply with quote

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: 327
Location: Montenegro

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 11:40 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 19, 2022 1:35 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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