Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

reading uart using pic18f

Status
Not open for further replies.

samizard

Junior Member level 2
Joined
Oct 27, 2017
Messages
23
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
198
hello guys,
i am using pic18f97j60 with c18 compiler and at 9600 baudrate.
currently i want to read response from uart which is a string.
i tried using functions given already -> BYTE ReadStringUART(BYTE *Dest, BYTE BufferLen) and void getsUSART(char *buffer, unsigned char len)
however when my program reaches to either of those functions,everything freezes.
apparently the problem i found was in while(!DataRdyUART()) line
can anyone help me solve this problem

Thanks.
 

Any receiving actions should be done by using interrupt. In main code you only check the ready flag. No point to explain, to much information in google available.
 

i checked on this problem but havent found any solution, probably the problem is in this part:-

Code:
char DataRdyUSART(void)
	{
        
		if(RCSTA2bits.OERR) //***
		{
			RCSTA2bits.CREN = 0; //***
			RCSTA2bits.CREN = 1; //***
		}
        
	  return PIR3bits.RC2IF;// .RCIF;//***
	}
 

The function clears Overflow error and returns the UART receive interrupt flag. If flag is set then it means data has been received and RCREG has to be read. You have to write code to read RCREG into a char type or char array[] variable.

Post your full code.
 

i am reading response of esp8266, the code is too big, but heres the part where i am getting error

Code:
char response;
....
....
....
putrsUART("AT\r\n"); //sending on uart
getsUSART(response,20); //reading uart

heres the code for getsUSART:-
Code:
void getsUSART(char *buffer, unsigned char len)
	{
	  char i;    // Length counter
	  unsigned char data;
	
	  for(i=0;i<len;i++)  // Only retrieve len characters
	  {
	    while(!DataRdyUSART());// Wait for data to be received
	
	    data = getcUART();    // Get a character from the USART
	                           // and save in the string
	    *buffer = data;
	    buffer++;              // Increment the string pointer
	  }
	}

or the code for Read string uart :-
Code:
BYTE ReadStringUART(BYTE *Dest, BYTE BufferLen)
{
	BYTE c;
	BYTE count = 0;
	while(BufferLen--)
	{
		*Dest = '\0';

		while(!DataRdyUART());
        
		c = ReadUART();

		if(c == '\r' || c == '\n')
			break;

		count++;
		*Dest++ = c;
	}

	return count;
}

even if i tried to increase the lenght of response in getsusart it doesnt work.
 

Hi,

it doesnt work.
...is no useful description.

--> describe what you expect and what you see instead.
Describe how you tried to test it, give the exact error description text, describe what you have done to debug your code.

Klaus
 

Ok........
so i have interfaced pic18f97j60 and esp8266 (it was a requirement to use those 2 together)
i have successfully uploaded data on internet, no problem there, now the only part remaining is that i have use esp response to make my system go further
say if i gave command to esp :- AT\r\n, then esp will respond with OK, if it is received then go further
i am using c18 compiler and got the uart functions from mla-2013
so after sending command to esp i used getsuart() function but the pic got freezed because the RC2IF bit was not pulled down to 0
so i tried writing code without checking the RC2IF bit but all i got in response variable was NUL even though esp is working fine i mean when i check the response on realterm it shows OK but dont store in variable
then i tried to readuart in a for-loop but still same result

what i want is to store esp response and compare it with a string, and what i get is nul
 

I suggest to step back to Easyrider83's comment. It's just expectable that processor activity freezes before a valid <CR> or <LF> is received. Under circumstances, you never receive a line end due to baud rate mismatch, hardware problems or whatsoever.
 

esp response for AT\r\n will be AT\r\n\r\nOK\r\n. You have to check this response.
 

any suggestion on how can i debug this problem??

one thing i observed in realterm is that when esp response is received then 1st line is blank and 2nd line contains the response character, this is same for every command sent to esp. so can it cause problem of not receiving correct bits??
 

8266 is an ARM processor itself. It is super-duper-ultra-mega stupid to use it together with 8-bit PIC
 

as mentioned before, that there are requirements for which i have to use those 2 together.................so can anyone tell me do i debug this problem
 

Post your complete code so that somebody can try to help you as soon as possible.
 

there are too many files of code and i am using the code by doing changes in mla-2013 Demo-App file

- - - Updated - - -

is there anyway to read rcreg without waiting for rcif to set..??
 

is there anyway to read rcreg without waiting for rcif to set..??
Only interrupt. Even for high density arm processor even having DMA onboard we anyway needs to use interrupts when data is received. The only defference that with DMA you can read multiple bytes in a row, but the whole approach it similar.
 

is there anyway to read rcreg without waiting for rcif to set..??
Not if you want to read a valid value - see Figure 21-6 of the MCUs datasheet to see why. Basically the RCxIF bit is set when a valid value is placed into the RCREGx register.
As Easyrider83 has pointed out, if you are using interrupts (i.e. RCxIE is set) then the ISR will be called when the hardware sets this bit. If you are using a blocking function (as your code seems to be) then you must wait until the bit is set.
One problem you might be encountering is that you are waiting until your command string is completely sent before you start to read any response. I have no idea how you have programmed the ESP2866 but if it is echoing the characters it is receiving then you will almost certainly run into problems.
The PIC18F97J60 can receive one character which it puts into the RCxBUF register while it is receiving the next. However if you do not read the first character (from RCxBUF) before the next character reception is complete, then you get an overrun condition (the OERR bit will be set) and basically the Rx side of the EUSART will stop working until you clear the problem.
If the ESP2866 is echoing characters back to you while you are sending the command then this will almost certainly occur.
The way around it is to use a ISR on the EUSART Rx side to write into a buffer. That way you will be processing any and all characters as they are being received, even while you are sending the command string.
When you are wanting the response, you can look at the buffer from your main code and (presumably) wait for the trailing "\r\n" before interpreting it.
Looking at the code you have written so far and the fact you are asking this question at all, I would suggest that you try something a little simpler to gain familiarity with using an ISR and buffer to receive characters - perhaps connect the Tx and Rx pins together and make sure that you can receive a test string that you send. Once you can do that, then you will have a working, interrupt driven reception process and can get back to your current problem, knowing that this part (at least) is working.
Susan
 

Code:
[COLOR="#FF0000"][SIZE=4]char response[/SIZE][/COLOR];
....
....
....
putrsUART("AT\r\n"); //sending on uart
[COLOR="#FF0000"][SIZE=4]getsUSART(response,20);[/SIZE][/COLOR] //reading uart

heres the code for getsUSART:-
Code:
void [COLOR="#FF0000"][SIZE=4]getsUSART(char *buffer, unsigned char len)[/SIZE][/COLOR]
	{
	  char i;    // Length counter
	  unsigned char data;
	
	  for(i=0;i<len;i++)  // Only retrieve len characters
	  {
	    while(!DataRdyUSART());// Wait for data to be received
	
	    data = getcUART();    // Get a character from the USART
	                           // and save in the string
	    *buffer = data;
	    buffer++;              // Increment the string pointer
	  }
	}
[/CODE]
You write to memory not owned by your program.
Should you allocate enough bytes (at least 21),you will be able to read the string without your program crushing.

Code:
[COLOR="#FF0000"][SIZE=4]char response[21][/SIZE][/COLOR];
....
....
....
putrsUART("AT\r\n"); //sending on uart
[COLOR="#FF0000"][SIZE=4]getsUSART(response,20);[/SIZE][/COLOR] //reading uart
 

the problem got resolved by passing the length of bytes to be received...

is there a way to implement timeout for rcif bit...???
 

Yes - start a timer that is reset when you detect the xxIF bit being set. If the bit is not set then the timer will timeout and generate its own interrupt.
That is but one way - there are no doubt many others.
Susan
 

I am trying to implement that
Thanks
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top