Forum: Mikrocontroller und Digitale Elektronik PIC Mikrocontroller UART READ


von Leonidas T. (helpleo)


Lesenswert?

Hey everybody, its nice to be part of the forum. I could use a little 
help.
I got stuck.
So basically i have the Travos 3 modul and i am sending data ("Hello 
World!") via HTerm, to my other Travos 3 funkmodul on my board. I want 
to store the data in an array and send it back ( with my PIC18F27Q43)
But it does not work :((

char payload[16] = {0};

     while (UART5_is_rx_ready()){
     payload[i] = UART5_Read();
     i++;
}

      if (payload[1] == 0x81){

            UART5_Write(0x02);
            UART5_Write(0x00);
            UART5_Write(0x0C);
            UART5_Write(0x48);
}

von Peter D. (peda)


Lesenswert?

Transmitting a byte over the UART need time. Thus the receive buffer was 
empty, most of the time.

You need to establish a protocol, whereby the receiver was able to 
determine the end of a message. And then collect all received bytes 
until the end was detected.
On text messages it was easy, to use CR+LF as end sign.

A poor solution was also, to use a timeout counter, to assume, the 
message was finished, if a certain time no more bytes are received.

von Leonidas T. (helpleo)


Lesenswert?

Thats helpfull, thanks.
But i just find out that i can store only to bytes.

// from data sheet
The UART module includes the following capabilities:
- Half and Full-duplex asynchronous transmit and receive
- Two-byte input buffer    !!!!!
- One-byte output buffer

And its true, cause when i put an led in the while loop. It will blink 
only two times and then leave the while loop.

while (UART5_is_rx_ready()) {

            LATBbits.LATB3 = 1;
            __delay_ms(100);
            payload[i] = UART5_Read();
            i++;
            LATBbits.LATB3 = 0;
            __delay_ms(100);
        }

Is it a way i can extend the buffer??

Thanks a lot for answering

von Tobias S. (herrgesangsverein)


Lesenswert?

"It does not work" is a very general description.
I use a lot of UART in my pic projects. Likely it is a configuration 
issue.
My suggestions:
* most likely your receive loop is broken. It will wait infinitely for 
new characters and out does not break after 16 characters which will 
overwrite other memory.
* try immediate echo within the loop. There is enough time if you set 
the pic tact rate high enough.

If this is not a problem for you, then:
* set up a test project just for the uart and use mcc for the 
configuration. It will set pin mapping, baud rate, and IO right.
* use the pin grid view to check the pin assignment
* I remember that maybe not all uarts have the same capabilities. You 
use uart5 which means there many squeezed in the pic
* check baud rates
* check the signal with an oscilloscope
* you cannot do step by step debugging while receiving. It will spoil 
the timing.
* you would want to design a more sophisticated protocol to mark begin 
and end of a message.

von W.S. (Gast)


Lesenswert?

Leonidas T. schrieb:
> I got stuck.
> So basically i have...

I think, you need some more skills. So I try to explain the basics of 
any serial transmissions:
On the receiver side you will never know, if and when a character is 
received and ready to use. So your serial driver needs to establish some 
kind of buffering to separate the transmission side from the usage side. 
With bigger controllers usually a circular buffer for 32 or more 
characters is established, but programming a PIC needs some kind of 
economical behaviour, so the circular buffer for the receiving direction 
may be made smaller. If you write your code in a rather not blocking 
manner, I think, a buffer of 8 places will work good enough.
On the transmitting side you usually want to have a bigger buffer, 64 
places or more. This is, because you often want to send a message 
without need to calculate the needed time for the actual transmission, 
so the message needs enough place in the buffer. Keep in mind, that the 
actual transmission ist rather slow, but it is to be handled in the 
interrupt service routines.

So your kind of programming should be rather event-driven. Please note 
the differences in the 2 Examples:

At first the rather stupid version:
1
int main (...)
2
...
3
forever:
4
{ wait_for_UART_is_ready();
5
  Ch = Get_the_character_from_UART();
6
  Do_something_with_it(Ch); 
7
  Do_somehing_else();
8
}

Here the event driven version:
1
int main (...)
2
...
3
forever:
4
{ if (Is_Character_available())
5
  { Ch = Get_the_character_from_UART();
6
    Do_something_with_it(Ch); 
7
  }
8
  Do_somehing_else();
9
}

Please note, that "Is_Character_available()" does not necessary refer to 
a UART, it shows instead, if some useable character is waiting 
(somewhere) to be fetched, but the calling program does not need, to 
handle any of the duties of the driver - or even know, if it's a UART or 
a riding messenger from Mars delivering a character.

In short: never handle low level duties in your firmware parts, let them 
be handled in a device driver, who separates the actual transmission 
problems from the "user"-level.

W.S.

von Leonidas T. (helpleo)


Lesenswert?

W.S. schrieb:

Thanks a lot guys, it worked fine. I just incrised the reciever buffer.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.