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.

UART Communication for Sending Integer Values

Kittu20

Member level 2
Joined
Oct 18, 2022
Messages
52
Helped
1
Reputation
2
Reaction score
0
Trophy points
6
Activity points
427
Hello everyone,

I'm trying to wrap my head around a basic concept. I want to retrieve an integer value from a variable in my microcontroller and send it to my PC via UART. The UART is configured for 8N1 format. Now, I know that an integer takes up 4 bytes of memory, but UART can only send or receive one byte of data at a time. How can I display an integer value like 12345 without using the string.h header file?
 
I'm trying to wrap my head around a basic concept.
You didn't mention anything about the programming language, compiler and/or whether you want such values to be visible in a terminal; so the question is a bit vague, but the obvious answer is, split the value into bytes and output them by adding arbitrary delimiter to the start or end of the number.
 
Hi,

UART can only send or receive one byte of data at a time
indeed just one single bit a time.

"Integer value" depends on microcontroller. It may be 8bit, 16 bit or 32 bit, maybe even 24 or 64 bits.

So let it be 32 bits. Signed or unsigned? Do you need the full range ?

So basically when you want to send more bytes .. you need some kind of frame .. and some kind of frame sync.
Frame sync may be bit_coded, byte_coded, or timing controlled, or you use an extra bit in the UART ( for example 9N1), or any other method.
.
Timing: send 4 bytes in a row, then wait minimum time (let´s say 50ms).
This is good when you expect a low average data rate.

For a high data rate you may use a bigger frame, maybe 64 x 4 bytes in one frame.

As said: you need frames everywhere you send more than 1 byte. And this is the usual way, thus you will find frames in almost any communcation: USB, Profibus, ModBus, Ethernet, Bluetooth, Morse, SPI, I2C, WiFi, IR remote control, every digital audio format, TV analog & digital ... you can find it everywhere.

Even this text uses spaces as "frame_sync" for words. Dots as frame sync for sentences.
New_lines for sections...

If you do an internet seach you will get many millions hits.

Klaus
 
As mentioned already it depends on many things but if you are sending the integer in the format it is stored, as say four bytes in 8-bit bytes, you can do it like this:

send - value shifted three times to the right
send - value shifted two times to the right
send - value shifted once to the right
send - value ANDed with 0xFF

That sends the high byte first, if you want to do it the other way around so the low byte is sent first, just reverse the order of the lines.

Brian.
 
A key concept that is implied in all of the replies above but I feel is at the heart of this question is that the computer itself has no understanding of what any particular byte (or combination of bytes) means. It is all just bits.
We, as the humans that program and look at the bit patterns, apply the interpretation that says (for example) that the bit pattern 0b01010011 can be the decimal number 83, an ASCII character that represents the letter 'S', part of a bigger bit pattern (as in your 32-bit integer perhaps) or something else entirely (perhaps each bit says something is set or not).
Also the UART will simply take whatever 8-bit pattern you give it at one end and deliver that exact same bit pattern at the other. It also provides no interpretation of what the bits mean.
You need to review the questions that are asked above to properly understand how "*YOU*" are interpreting the bits and then you will know how to use the UART to send them form one place to another.
Susan
 
If you do an internet seach you will get many millions hits.

Klaus
I have wriiten code I get expected data on terminal when i use string.h header file it works fine. . please find function commanted in below program just having problem with bitshifting and masking approch
You didn't mention anything about the programming language, compiler and/or whether you want such values to be visible in a terminal; so the question is a bit vague, but the obvious answer is, split the value into bytes and output them by adding arbitrary delimiter to the start or end of the number.

MPLAB xc8 and pic18f45k80

As mentioned already it depends on many things but if you are sending the integer in the format it is stored, as say four bytes in 8-bit bytes, you can do it like this:

send - value shifted three times to the right
send - value shifted two times to the right
send - value shifted once to the right
send - value ANDed with 0xFF

That sends the high byte first, if you want to do it the other way around so the low byte is sent first, just reverse the order of the lines.

Brian.

I tried method you suggested but not getting expected data

C:
#define _XTAL_FREQ 8000000
#include <xc.h>
#include<string.h>
#include <stdio.h>


// Configuration bits: selected in the GUI
// CONFIG1L
#pragma config RETEN = OFF
#pragma config INTOSCSEL = HIGH
#pragma config SOSCSEL = DIG
#pragma config XINST = OFF
// CONFIG1H
#pragma config FOSC = INTIO2
#pragma config PLLCFG = OFF
#pragma config FCMEN = OFF
#pragma config IESO = OFF
// CONFIG2L
#pragma config PWRTEN = OFF
#pragma config BOREN = SBORDIS
#pragma config BORV = 3
#pragma config BORPWR = ZPBORMV
// CONFIG2H
#pragma config WDTEN = OFF
#pragma config WDTPS = 1048576
// CONFIG3H
#pragma config CANMX = PORTB
#pragma config MSSPMSK = MSK7
#pragma config MCLRE = ON
// CONFIG4L
#pragma config STVREN = ON
#pragma config BBSIZ = BB2K
// CONFIG5L
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CP2 = OFF
#pragma config CP3 = OFF
// CONFIG5H
#pragma config CPB = OFF
#pragma config CPD = OFF
// CONFIG6L
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRT2 = OFF
#pragma config WRT3 = OFF
// CONFIG6H
#pragma config WRTC = OFF
#pragma config WRTB = OFF
#pragma config WRTD = OFF
// CONFIG7L
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTR2 = OFF
#pragma config EBTR3 = OFF
// CONFIG7H
#pragma config EBTRB = OFF
 

 
void initializeOscillator(void)
{
    // Configure oscillator settings
    OSCCON = 0x60;
    OSCCON2 = 0x00;
    OSCTUNE = 0x00;
    REFOCON = 0x00;
}
 
void initializeEUSART1(void)
{
    // Configure EUSART1 settings
    BAUDCON1 = 0x08;
    RCSTA1 = 0x90;
    TXSTA1 = 0x24;
    SPBRG1 = 0xCF;
    SPBRGH1 = 0x00;
}
 
 
void sendCharacter(char message)
{
    while (TXIF == 0);
    TXREG1 = message;
}
 
void sendString(char *str)
{
    while (*str != '\0') {
        __delay_ms(1);
        sendCharacter(*str);
        str++;
    }
}

/*void sendInteger(int num)
{
    char buffer[20];  // Buffer to hold the string representation of the integer
    sprintf(buffer, "%d\r\n", num);  // Convert integer to string

    sendString(buffer);  // Send the string
}*/

void sendInteger(int num)
{
    // Send the high byte first
    sendCharacter((num >> 24) & 0xFF);

    // Send the next byte
    sendCharacter((num >> 16) & 0xFF);

    // Send the next byte
    sendCharacter((num >> 8) & 0xFF);

    // Send the low byte
    sendCharacter(num & 0xFF);
}

void main(void)
{
    TRISC = 0xBF;
    initializeOscillator();
    initializeEUSART1();
    __delay_ms(5000);
  
 
    while (1)
    {
       int valueToSend = 12345;

       sendInteger(valueToSend);
    
         __delay_ms(5000);
    
    
    }
}

1693473038449.png
 
You need to review the questions that are asked above to properly understand how "*YOU*" are interpreting the bits and then you will know how to use the UART to send them form one place to another.
Unfortunately Kittu20 yet didn't, I believe they didn't even understand the problem involved with sending unformatted binary data, as the latest post suggests. You are sending binary data but displaying ASCII data in Tera Term.

The code is sending unformatted 32 bit data, it could be possible to receive it without additional framing by using the delay between 4 character packets as delimiter. To see if the uC is sending expected data, you'll however need to use a binary receiver application, not sure if Tera Term has the feature.

I personally avoid to send plain binary data over serial interface. Use hex encoding which doesn't need much computing overhead, just double the number of serial characters. You are actually sending int16 data (the default int format of xc8), so it can be still hex coded by 4 characters, but it's readable in Tera Term. I would also prefer some kind of framing, e.g. <CR> or <CR><LF> packet delimiter. This avoids delay detection at the receiver side and further improves human readability.
 
Hi,

You want to display the "integer value" in TeraTerm?

That´s a totally different problem!
TeraTerm (and many other terminal software) can not transform a 32 bit (4 byte) integer into ASCII characters.

Usually terminal softwarer can represent only single bytes
* as HEX
* as decimal
* as binary
* as ASCII

--> Please read TeraTerm documentation.

Klaus
 
This is one approch to display integer value on terminal. I wanted to try bit shifting and masking approch

1693478347772.png
 
Hi,

your integer (signed, 16 bit like FvM says) is now converted to
0x31, 0x32, 0x33, 0x34, 0x35, 0x0D, 0x0A
and transmitted as those 7 bytes via UART to the terminal program.
The terminal program is set up to represent each received byte as an ASCII character.

This "12345" plus the "frame sync" [Cr] and [Lf] is shown on the Terminal´s screen"

Klaus
 

LaTeX Commands Quick-Menu:

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top