- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good morning,
I'm using Uart but I have some problems because I can't copy the characters i saved in a software buffer in a string and then send it back.
If i send back the RxBuffer using UART_PutString(),it works!
I Checked the examples on this forum but I would to realize something extremely simple to understand how Uart component works.
Where I'm getting wrong?
Solved! Go to Solution.
- Labels:
-
PSoC 5 Architecture
-
PSoC 5LP
- Tags:
- uart
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The nature of UART is asynchronous and character oriented. This implies a couple of restrictions.
At first there is no standard protocol using UART. When you want to handle messages (i.e.. a "string") you need to implement this yourself. Done easiest by defining an end-of-message character as EOL or NULL
Since asynchronous means you do not know when characters will be transmitted and nobody knows if at that moment you have time to poll for incoming chars best practice is to have a buffer defined and let the component handle thie get and puts from/to the buffer.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
marcogiorio,
There are many issues In your code:
CY_ISR(RxIsr_Handling){
rx_ClearPending();
RxWriteIndx=RxBuffer;
//Check on interrupt
while((UART_RX_STS_FIFO_NOTEMPTY) != 0u && UART_GetRxBufferSize()!=0){
*RxWriteIndx++=UART_ReadRxData();
}
*RxWriteIndx='\0'; // this just killed last character received !!!
// UART_PutString(RxBuffer);//check on interrupt // Do not put slow UART communication inside interrupt!!!
flag_rx=1;
}
int main(void)
{
CyGlobalIntEnable;
UART_Start();
UART_PutString("Hello world");
rx_StartEx(RxIsr_Handling);
for(;;){
if(flag_rx==1){
flag_rx=0;
for(i=0;RxBuffer!='\0';i++)
MyString=RxBuffer;
//MyString='\0'; // This line kills current character !!!
UART_PutString(MyString);
UART_ClearRxBuffer();
UART_ClearTxBuffer();}
}}
The CY_ISR(RxIsr_Handling) above does not guaranty receiving long message, it is basically starts from scratch on any CY_ISR interrupt - no good for anything besides 1-byte message. UART communication protocol usually has some termination character to indicate the end of the message (LF, CR). You can find example of UART command messaging here:
UART string reception garbage value
/odissey1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I modified your main.c as below
in this example, when SPACE(' '), TAB('\t'), CR('\r') or LF(\n') is detected
program complete current word and print out it with a new line.
The device is changed to CY8C5868AXI-LP035 for CY8CKIT-050
but main.c should work for your board, too.
main.c
=======================
#include "project.h"
#define SIZE 80
#define SPACE ' '
#define TAB '\t'
#define LF '\n'
#define CR '\r'
uint8 flag_rx=0;
char RxBuffer[SIZE];
char *RxWriteIndx;
char MyString[SIZE];
int BufIndex = 0 ;
CY_ISR(RxIsr_Handling)
{
uint8_t c ;
rx_ClearPending();
if (UART_GetRxBufferSize() > 0) {
c = UART_GetChar() ;
// if ((c == LF) || (c == CR)) { // allow space and tab in a word
if ((c == SPACE) || (c == TAB) || (c == LF) || (c == CR)) {
RxBuffer[BufIndex] = (char)NULL ;
flag_rx = 1 ;
BufIndex = 0 ;
} else {
RxBuffer[BufIndex++] = c ;
}
}
}
int main(void)
{
int i ;
CyGlobalIntEnable;
UART_Start();
UART_PutString("\n\rHello world\n\r"); /* new line added */
rx_ClearPending() ;
rx_StartEx(RxIsr_Handling);
for(;;){
if(flag_rx == 1){
flag_rx=0;
#if 1 // I don't think we need to copy RxBuffer to My String
// So if you use only RxBuffer, change 1 to 0
for(i=0;RxBuffer!='\0';i++) {
MyString=RxBuffer;
}
MyString='\0';
UART_PutString(MyString);
#else
UART_PutString(RxBuffer) ;
#endif
UART_PutString("\n\r") ;
}
}
}
=======================
FYI,
actually following three lines should work
==================
for(i=0;RxBuffer!='\0';i++)
MyString=RxBuffer;
MyString='\0';
==================
but I recommend you
(1) at least use indentation
==================
for(i=0;RxBuffer!='\0';i++)
MyString=RxBuffer;
MyString='\0'; /* this line is not in the loop */
==================
(2) even for better maintenance use { }
==================
for(i=0;RxBuffer!='\0';i++) {
MyString=RxBuffer;
}
MyString='\0';
==================
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Guys, thank you!!!!
Actually you let me to understand how the UART module works.
I thought the internal interrupt could store in my software buffer all the ASCII string I sent by terminal in only one time,i.e it is executed just one time to move all data from internal hardware buffer to my software buffer.
I didn't understand why this isn't possible, is it a psoc limit? or this happen to all mcu?
Anyway I understood the interrupt is executed for every single ASCII, UART_GetChar() let me to read char by char and store it in a software buffer in order to manage a string as I want.
Please tell me if I'm getting wrong.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I think your understanding is correct.
But please note that there are "many" ways to do a thing correctly.
And I'm afraid that I have one more thing I should mention,
which I did not cover in my sample, is "buffer overrun".
If the currently receiving word is "longer" than SIZE-1 we are in trouble with my sample.
So if you'd like to also take care of it (usually we must) modify the line
> RxBuffer[BufIndex++] = c ;
to
RxBuffer[BufIndex++] = c ;
if (BufIndex >= (SIZE-1)) {
RxBuffer[BufIndex] = (char)NULL ;
flag_rx = 1 ;
BufIndex = 0 ;
}
to terminate the word before causing buffer overrun.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The nature of UART is asynchronous and character oriented. This implies a couple of restrictions.
At first there is no standard protocol using UART. When you want to handle messages (i.e.. a "string") you need to implement this yourself. Done easiest by defining an end-of-message character as EOL or NULL
Since asynchronous means you do not know when characters will be transmitted and nobody knows if at that moment you have time to poll for incoming chars best practice is to have a buffer defined and let the component handle thie get and puts from/to the buffer.
Bob