UART question

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
Hi
I made a function flow diagram to understand Uart communication as per my knowledge.

If you find something wrong, I will appreciated any suggestion to improve it.

This chart can only send or receive a single byte. I do not understand how to make it to write/read multiple bytes ?


1579259832512.png
 

JohnInTX

Joined Jun 26, 2012
4,787
The handling of transmit and receive IS basically correct but you have some problems.
There is a branch between 'Receive byte' and Stop but there is no test. Which way does it go and when? If it loops, you can't do any other processing. If it Stops and returns, you re-initialize the UART each time you call the routine, that won't do either.
You do not show how characters get passed in for transmit or returned after they are received.

At this level, the UART breaks down into 3 separate functions:
Init
Transmit a character
Receive a character

Why not break these down into 3 separate functions? That way, you can call them as many times as you want to send or receive many characters. When you have those working, you can use them to feed those circular buffers - highly recommended - to smooth things out. The general ideas will also work with interrupt-driven circular buffers (FIFOs).

The PDF shows one way to do the 3 functions. There is room for improvement but hopefully you get the basic idea.

EDIT: the receive function polls TRMT, it should poll TXIF. PDF updated
 

Attachments

Last edited:

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
At this level, the UART breaks down into 3 separate functions:
Init
Transmit a character
Receive a character

The PDF shows one way to do the 3 functions. There is room for improvement but hopefully you get the basic idea.
i will try to understand by writing some code. Program suppose to send three bytes to computer

C:
// CONFIG
#pragma config FOSC = HS       // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF       // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
// End of configuration

#include <xc.h>
#define _XTAL_FREQ 20000000
#define Baud_rate 9600

void Initialize_UART(void)   //Initializing UART module for PIC16F877A
{ 
    TRISC6 = 0; // TX Pin set as output
    TRISC7 = 1; // RX Pin set as input
  
    /**Initialize SPBRG register for required
    baud rate and set BRGH for fast baud_rate**/
    SPBRG = ((_XTAL_FREQ/16)/Baud_rate) - 1;
    BRGH  = 1;  // for high baud_rate
  
    SYNC  = 0;    // Asynchronous
    SPEN  = 1;    // Enable serial port pins

    TXEN  = 1;    // enable transmission
    CREN  = 1;    // enable reception
  
    TX9   = 0;    // 8-bit reception selected
    RX9   = 0;    // 8-bit reception mode selected 
}

void UART_send_char(char message)  //Function to send one byte of date to UART
{
    while(!TRMT);  // Wait till the transmitter register becomes empty
    TXREG = message; //load the char to be transmitted into transmit reg
}

// Sends null-terminated ASCII string
void UART_send_string(char* p)
{
     char c;
     while((c = *p) != '\0')
     {
        UART_send_char(c);
        p++;
     }
}

void main(void)  // START of Main Function
{
    Initialize_UART();    //Initialize UART module                 
  
    UART_send_string("1");   //pass first byte only
    UART_send_string("2");   // pass second byte only
    UART_send_string("3");   // pass third byte only
}
I have few doubts

1579359073865.png
1) Do we send three bytes like shown above ?

2) When TRMT become enabled and disable during transmission of three bytes ?
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
1) Do we send three bytes like shown above ?
Not sure what you are asking but yes, the code will send 123 to the UART at 9600 baud. The signals you show are generated by the hardware and you don't need to worry about them unless you have problems or just want to see them with an oscilloscope.

Also, you are sending the 3 bytes as 3 separate strings. Your UART_send_string function will handle NUL-terminated strings of any length so why not do that?
C:
UART_send_string("123"); // does the same thing as 3 calls.
2) When TRMT become enabled and disable during transmission of three bytes ?
My error. I should have said TXIF, not TRMT. Change your code to use TXIF. Sorry.
The UART is double buffered. That means you can write one byte to TXREG while the previous byte is being sent. TXIF == 1 means that the buffer is ready to accept another character and cleared when you write a character to TXREG to indicate that the buffer is full. When the current character is sent, TXIF will be set again, indicating you can write the next character to TXBUF.
Setting and clearing of TXIF is done by the UART hardware.

EDIT: A small point.
UART_send_char(char message)
The name 'message' implies more than one character. A better name for the passed parameter would be just c. That is consistent with your other routines.

C:
void UART_send_char(char c)  //Function to send one byte of data to UART
{
    while(!TXIF);  // Wait till the transmitter register becomes empty by polling TXIF (not TRMT)
    TXREG = c; //load the char to be transmitted into transmit reg.  This clears TXIF automatically.
}
 
Last edited:

MaxHeadRoom

Joined Jul 18, 2013
28,688
There is a technical APP note on the PicMicro site on UART functions and methods several for the 16F and 18F with example programs.
They are written in Assembly, but could be converted to C if needed.
Max.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
Not sure what you are asking but yes, the code will send 123 to the UART at 9600 baud.
My question is, will I need start bit and start bit every time if I send more than one byte

1579368097170.png
As you can see I have used the start bit and stop bit three times.


Either I should use start and stop bit only once As given in the below diagram

1579368600876.png
 

nsaspook

Joined Aug 27, 2009
13,277
My question is, will I need start bit and start bit every time if I send more than one byte

View attachment 197128
As you can see I have used the start bit and stop bit three times.


Either I should use start and stop bit only once As given in the below diagram

View attachment 197131
The start/stop bits are hardware programmed UART synchronization events (start-ready receive buffer time interval/stop-buffer store or execute function time interval) for the encapsulated data for the transmit to receive mechanism (originally a mechanical buffer but mainly electronic today).


If the data buffer is 8-bits then synchronization is needed around each 8-bit load. If the actual (24N1is unlikely) UART data load is 24-bits (the transmitter and receiver buffer 24-bits of data) then synchronization is needed around the 24-bit load.
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
My question is, will I need start bit and start bit every time if I send more than one byte
No, YOU won't need a start and stop bit every time. You are not bit banging, you are using a hardware peripheral that knows how to do it. The asynchronous protocol used by the UART does need start and stop bits but the UART does it automatically for each byte sent. All you have to do is write the character to TXBUF and everything else is done for you.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
No, YOU won't need a start and stop bit every time. You are not bit banging, you are using a hardware peripheral that knows how to do it. The asynchronous protocol used by the UART does need start and stop bits but the UART does it automatically for each byte sent. All you have to do is write the character to TXBUF and everything else is done for you.
Hi JohnInTX

This means that my second diagram is correct. This indicates that communication has started and we can send one or more bytes.
Communication will stop after the last byte

My other doubt is that if we want to send only 4 bits of data, then how can we do this via uart?

I think we will need to use bit wise operator to send only 4 bits, Am I right ?
 

nsaspook

Joined Aug 27, 2009
13,277
Your second diagram is 24N1 instead of the much more common 8N1, that's unlikely to be correct on a common microcontroller hardware UART. It's possible to create a 24N1 hardware UART with a FPGA but the utility of that is questionable.
 

JohnInTX

Joined Jun 26, 2012
4,787
This means that my second diagram is correct. This indicates that communication has started and we can send one or more bytes.
Communication will stop after the last byte
NO. The PIC UART sends one 8 bit character with start and stop bits for each byte you write to TXREG. To send more than one byte, write each byte to TXBUF when TXIF==1. That's ALL you need to know. You are confusing UART with I2C. Don't. They are completely different protocols.
My other doubt is that if we want to send only 4 bits of data, then how can we do this via uart?
The UART always sends 8 bits. Period. You can send a 4 bit value but it must be padded to 8 bits. 0000dddd.
I think we will need to use bit wise operator to send only 4 bits, Am I right ?
NO. You are thinking bit-banging again.

Why are you making this so hard? Configure the UART then write each character to TXREG. That is all it takes. You wrote the code to do that above. Do you not understand what you wrote??
 
Last edited:

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
Why are you making this so hard? Configure the UART then write each character to TXREG. You wrote the code to do that above. Do you not understand what you wrote??
@JohnInTX Thanks

I know what's happening in the program I was clearing my some doubts. I have more doubts but first i try to find myself then I will ask If I don't understand anything

This is the last doubt for now, What happen if I want to send 1GB data of sensor to PC via UART. Suppose there is a sensor that gives different values every time and we are sending that value to PC.

I think MCU will read 1 byte from sensor and it will load 1 byte to TXREG when it completes it will load next byte to TXREG up to 1GB data.
We do not need to store the sensor data inside MCU
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
I think MCU will read 1 byte from sensor and it will load 1 byte to TXREG when it completes it will load next byte to TXREG up to 1GB data.
We do not need to store the sensor data inside MCU
1 GB?? :eek: You do know that 1GB will take almost 13 days to send at 9600 baud?

But, sure, you can do that as long as the sensor rate < the UART rate because you sure are not going to store much in the PIC16F877A.

At 9600 baud, it takes 1.04ms to send one 8 bit byte. If the sensor generates bytes slower than that, you are OK. If it generates bytes faster than that you have to change things. Possibilities are:
  • Faster baudrate. 115200 baud sends a byte in about 86.8 microseconds.
  • If the sensor data comes in bursts you can use a buffer (#2) to hold the data from the sensor while you transmit to the UART.
  • Some sort of flow control between the PIC and the sensor so that the PIC can tell the sensor not to send anything more until the previous data is sent.
 
Last edited:

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
If the sensor data comes in bursts you can use a buffer to hold the data from the sensor while you transmit to the UART.
Some sort of flow control between the PIC and the sensor so that the PIC can tell the sensor not to send anything more until the previous data is sent.
Please take a look at diagram in link https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter

1579378826652.png

This is confusing me there is parity bit after 7 bit but we don't do that

We set parity bit only in the hyper terminal on PC
 

JohnInTX

Joined Jun 26, 2012
4,787
This is confusing me there is parity bit after 7 bit but we don't do that
That's right. Your UART is configured for 9600,N,8,1
9600 baud
No parity
8 bits of data
1 stop bit.

The UART in the picture is configured for 9600,O,8,1:
9600 baud
ODD Parity
8 bits of data
1 stop bit.

While the PIC can send and receive an extra bit for parity, it DOES NOT have a built-in parity generator or parity checker. You have to do that in firmware. Most PIC stuff is just 9600,N,8,1 as a result. Use that.

Both the PIC and HyperTerminal on the PC must be configured the same.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
That's right. Your UART is configured for 9600,N,8,1
I saw the datasheet of pic16f877a It has inbuilt USART not UART so USART can operate in both mode Asynchronous/Synchronous

UART : Universal Asynchronous Receiver/Transmitter.
USART: Universal Synchronous Asynchronous Receiver/Transmitter

USART require external clock https://en.wikipedia.org/wiki/Universal_synchronous_and_asynchronous_receiver-transmitter

Does this mean that clock signals are sent with every single bit in USART?
 

JohnInTX

Joined Jun 26, 2012
4,787
Does this mean that clock signals are sent with every single bit in USART?
USART stands for Universal Synchronous / Asynchronous Receiver Transmitter. This means that the USART in the PIC can run in one of two modes: either synchronous, which uses a clock and data (like SPI) or asynchronous which does not use a separate clock.
At your level, for communicating with a terminal or PC, you would want to confugure the USART for asynchronous mode so I dropped the 'S' from the name.
Good question, though!
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
At your level, for communicating with a terminal or PC, you would want to confugure the USART for asynchronous mode so I dropped the 'S' from the name.
Good question, though!
I understand UART but I do not understand exactly what happen in USART
1579403086864.png

When does USART Send or receive data ? When does communication begin and end ?
 
Top