• AVR Freaks

Helpful ReplyHot!How to transmit and read a 16 bit data using UART?

Page: 12 > Showing page 1 of 2
Author
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
2019/05/26 01:40:19 (permalink)
0

How to transmit and read a 16 bit data using UART?

My goal is to write and read 16-bit array containing hex-decimal value.
But before that I want to get the 16-bit array transmission while converting a decimal to its equivalent hex value.
controller: PIC16F877A
I tried to write the code but was not successful in making it work  
My current code is as follows 
 
#include <xc.h>
#include<stdio.h>
#include<stdlib.h>
/*------------sub function to send a char----------*/
void UART_send_char_(char bt)
{
    while(!TXIF); // hold the program till TX buffer is free
    TXREG = bt; //Load the transmitter buffer with the received value
}

/*-------------function ends------------*/

/*----------sub function to send a string------*/

void UART_send_string(char* st_pt)
{
    while(*st_pt) //if there is a char
        UART_send_char_(*st_pt++); //process it as a byte data
}

/*-----------function ends--------------*/


/*----------sub function to receive a char------*/
char UART_get_char_()
{
    if(OERR) // check for Error
    {
        CREN = 0; //If error -> Reset
        CREN = 1; //If error -> Reset
    }
    
    while(!RCIF); // hold the program till RX buffer is free
    
    return RCREG; //receive the value and send it to main function
}

/*-----------function ends--------------*/
void main(void)
{
   
    long int hex_value,quotient;
     char buffer[16];
     int i=0;
 int lo_byte, hi_byte;
     int get_value;

     //printf("Enter any decimal number: ");

     get_value=UART_get_char_();

 lo_byte = get_value & 0xFF;
 hi_byte = get_value >> 8;

     
     for (i=0;;)
  {
  while(quotient!=0)
  {
            int temp=0;
   quotient = lo_byte;

       temp = quotient % 16; //(%) gives reminder

       //To convert integer into character

       if( temp < 10)
              temp =temp + 48;
                else
              temp = temp + 55;
       hex_value= temp;
                 itoa(hex_value,buffer,16);
                
       quotient = quotient / 16;
  }
   UART_send_string(buffer);
  i++;
  
  while(quotient!=0)
  {
            int temp=0;
   quotient = hi_byte;

       temp = quotient % 16; //(%) gives reminder

       //To convert integer into character

       if( temp < 10)
              temp =temp + 48; else
              temp = temp + 55;
       hex_value= temp;
                itoa(hex_value,buffer,16);//---1
       quotient = quotient / 16;
  }
   UART_send_string(buffer);//---2
     }
}

 
Remove the "_" after "char" in the code.
 
I get warning at build time regarding illegal conversion of integer to pointer and pointer to integer at comment"1", and between pointer types at"2".
 
Please help.
Thanks in advance.
 
#1
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/26 02:29:00 (permalink)
+2 (2)
What are you trying to do here?
 get_value=UART_get_char_();
 lo_byte = get_value & 0xFF;
 hi_byte = get_value >> 8;

UART_get_char_() returns a char   (8 bits), so it will always be stored in lo_byte, and hi_byte will always be zero.

Here:
 itoa(hex_value,buffer,16);//---1

should be
 itoa(buffer,hex_value,16);//---1

What is the precise error message you get on this line?
   UART_send_string(buffer);//---2



Also, I don't understand why your code is trying to manually construct the output, when itoa() would do all the work for you.
 
post edited by qhb - 2019/05/26 02:40:23

Nearly there...
#2
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/26 02:53:09 (permalink)
0
qhb
What are you trying to do here?

 
I'm trying to split the 16bit value into two 8bit values.

What is the precise error message you get on this line?
   UART_send_string(buffer);//---2


 
 warning: (359) illegal conversion between pointer types

Also, I don't understand why your code is trying to manually construct the output, when itoa() would do all the work for you.
 

 
I have tried many logic and commands and none of worked. I'm trying this one now.




#3
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/26 03:19:59 (permalink)
+1 (1)
Abhishek ms
qhb
What are you trying to do here?

I'm trying to split the 16bit value into two 8bit values.

What 16 bit value?
As I already mentioned, you have just received ONE character via the serial port.
A character is 8 bits.
 


What is the precise error message you get on this line?
   UART_send_string(buffer);//---2


 warning: (359) illegal conversion between pointer types

Did you post EXACTLY the code you are testing?
I notice there are no config settings here, which leads me to think you're not posting all of it.
 


Also, I don't understand why your code is trying to manually construct the output, when itoa() would do all the work for you.
 

I have tried many logic and commands and none of worked. I'm trying this one now.

Trying to do it manually AND use itoa() at the same time?
Just have a look in the XC8 User Guide for what the itoa() function does.
Used correctly, it replaces almost all the second half of your program.

Nearly there...
#4
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/26 04:39:17 (permalink)
0
 
qhb
As I already mentioned, you have just received ONE character via the serial port.
A character is 8 bits.
 

Ok I got it, so can you tell me the correct way to receive a 16bit 
 

Did you post EXACTLY the code you are testing?
I notice there are no config settings here, which leads me to think you're not posting all of it.

This is the whole code except for the configuration settings.
If you want me to post the configuration settings I will post them.
 
I will try to re-write the program using Library functions
 
#5
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/26 09:26:41 (permalink)
0
This is a code I was working on to learn about itoa library function.
Well it dosen't work but I think I got how it could replace half of my program.
I need to store a 10bit data which will be between 2000 to 6000.
The whole UART thing is only for testing if the logic works or not, after which I will use it in I2C and later in SPI, so I need to convert it into hexadecimal.  
#include <xc.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include"16F_only_tests_header.h"

/*------------sub function to send a char----------*/
void UART_send_char_(char bt)
{
    while(!TXIF); // hold the program till TX buffer is free
    TXREG = bt; //Load the transmitter buffer with the received value
}

/*-------------function ends------------*/

/*----------sub function to send a string------*/

void UART_send_string(char* st_pt)
{
    while(*st_pt) //if there is a char
        UART_send_char_(*st_pt++); //process it as a byte data
}

/*-----------function ends--------------*/

void main(void)
{
char buf[10];
itoa(buf, 2345, 16);
UART_send_string(buf);
return;
}

 
Is my approach correct or is there a better alternative?
 
#6
NKurzman
A Guy on the Net
  • Total Posts : 17599
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/26 09:57:06 (permalink)
0
You seem to be mixing how numbers are stored in a computer. Your 16 BIT numbers are stored in memory as 16 ones an zeros.
You can show them to people as binary, decimal or hexidecimal TEXT.
If you are transferring data between two computers you can send them as binary data. So for 16 bits that would be two bytes.
If you converted to text and send it, then that would be be 1 to 5 bytes for 16 bits.
But the receiving computer would need to convert it back to binary.
#7
1and0
Access is Denied
  • Total Posts : 9484
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/26 12:25:15 (permalink)
+4 (4)
Abhishek ms
This is a code I was working on to learn about itoa library function.
Well it dosen't work but I think I got how it could replace half of my program.

How do you know "it doesn't work"?  You have not setup the UART in your code.
 

I need to store a 10bit data which will be between 2000 to 6000.

10-bit data have values of 0 to 1023, not 2000 to 6000.
 

The whole UART thing is only for testing if the logic works or not, after which I will use it in I2C and later in SPI, so I need to convert it into hexadecimal.  
...
Is my approach correct or is there a better alternative?

Try using the SIMulator and see.
#8
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/26 23:16:38 (permalink)
0
My sincere apologies to you all.
It is my fault,out of frustration I forgot to add the UART initialization function in the program and did not understand the itoa function properly.
The sample program works but keeps sending the Hex value repeatedly. How can I stop this?
I think I have to introduce a NULL character somewhere but I do not Know where.
 
Thank you for replying
 
 
#9
PStechPaul
Super Member
  • Total Posts : 2342
  • Reward points : 0
  • Joined: 2006/06/27 16:11:32
  • Location: Cockeysville, MD, USA
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/26 23:51:14 (permalink)
+3 (3)
There is no way for us to help if you do not provide all of your code. Please save your entire project in a zipfile and attach it to a post so we can build and test it. What you are trying to do is very simple, but we don't have enough information.

 
#10
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/27 00:30:19 (permalink)
0
I have attached the project file as required.
I'm very sorry for the inconvenience.

Attachment(s)

Attachments are not available: Download requirements not met
#11
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/27 01:35:13 (permalink)
+1 (1)
Abhishek ms
The sample program works but keeps sending the Hex value repeatedly. How can I stop this?

That's exactly what you told it to do, with this line:
        for (i=0;;)

That pointlessly initialises your i variable, which is incremented inside your loop, but never used or tested.
 
Then this line is naughty
[code        while(quotient!=0) [/code]
You have not written anything to that variable yet, so it is "unknown", so it's pointless to test it at this point.
 
I note you are STILL copying the top 8 bits of get_value to hi_byte, even though I pointed out the futility of this many posts ago.
 
Why did you change this line to use base-8? I suspect you still don't understand how itoa() works. It is clearly documented in the XC8 User Guide.
                itoa(buffer,hex_value,8);



I really get the impression you are just flailing around and not bothering to actually read the answers or the documentation.
 
 

Nearly there...
#12
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/27 02:33:04 (permalink)
0
thank you for replying qhb
 
I'm sorry for not being clear.
The sample code is the one I posted in reply #6, which I built based on your suggestion of using the library function.
 
The code is as follows
 
#include <xc.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//#include<conio.h>
#include"16F_only_tests_header.h"
#define BAUD_RATE 9600
#define _XTAL_FREQ 8000000

void UART_init(void)
{
SPBRG = ((_XTAL_FREQ/16)/BAUD_RATE) - 1;
BRGH = 1; // for high baud_rate
 TRISC6 = 1; // TX Pin set as output
 TRISC7 = 1; // RX Pin set as input
  
    TXEN = 1; // enable transmission
    CREN = 1; // enable reception
    SYNC = 0; // Asynchronous
    SPEN = 1; // Enable serial port pins
    TX9 = 0; // 8-bit reception selected
    RX9 = 0; // 8-bit reception mode selected
}

/*------------sub function to send a char----------*/
void UART_send_char_(char bt)
{
    while(!TXIF); // hold the program till TX buffer is free
    TXREG = bt; //Load the transmitter buffer with the received value
}

/*-------------function ends------------*/

/*----------sub function to send a string------*/

void UART_send_string(char* st_pt)
{
    while(*st_pt) //if there is a char
        UART_send_char_(*st_pt++); //process it as a byte data
}

/*-----------function ends--------------*/


void main(void)
{
char buf[2]; //pointer of char type is treated as string
UART_init();

itoa(buf, 2345, 16);
__delay_ms(500);
UART_send_string(buf);
}

For the decimal value of 2345 the itoa function is returning the equivalent  Hex value of 929, but it is returning it infinite times.
So I want to Know how to make the itoa function return the value only ones.
The other Trouble I'm facing is that, I want to Read a 12bit binary value which is not possible in this PIC so I have to read the data twice(I think) which I am not able to figure out how.
 
Thanks in advance 
 

Attachment(s)

Attachments are not available: Download requirements not met
#13
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/27 02:52:03 (permalink) ☄ Helpfulby Abhishek ms 2019/05/27 03:26:16
+3 (3)
Abhishek ms
..
For the decimal value of 2345 the itoa function is returning the equivalent  Hex value of 929, but it is returning it infinite times.

No it is not.
It is returning the value precisely once.
Your code is printing it multiple times because you are allowing your main() function to exit, so it is restarting and immediately running the same code again, over and over.
Just add this line to the end of your main() function ifyou only want it to run once.
 while (1);    //loop forever

 

The other Trouble I'm facing is that, I want to Read a 12bit binary value which is not possible in this PIC so I have to read the data twice(I think) which I am not able to figure out how.

"This PIC" has nothing to do with your problem reading 12 bits.
Your problem is that you are trying to squeeze your 12 bits into a single character of the UART.
Even a 64 bit processor transfers characters 8 bits at a time over a UART.
You could simply send your data as two bytes, the upper and the lower byte seperately, but you then have to work out how you are going to know WHICH is the low byte, and which is the high byte.
i.e. if you do it more than once, it's easy to get out of synch, and end up with them swapped.
 
You mentioned this is only a test before you move on to I2C or SPI anyway.
So, do you really need to muck around trying to do it via the USART when that's not your end aim anyway?
When you use I2C or SPI, you will be transferring data in packets, so it's easy to determine which is the "first" byte of a multi-byte sequence.
 
 
 
post edited by qhb - 2019/05/27 02:54:04

Nearly there...
#14
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/27 08:19:11 (permalink)
0
Thank you for your suggestions all
I will take your advice and will switch to I2C.
But I need to get a 16bit(12bits in my case) input in decimal form which should be editable by a user interface, which I think is possible only by using UART.
So Now I need to Get the 16bit value, convert it into hex equivalent value and send it to EEPROM for future use.
There are two problems I'm facing while doing this,
1. Is my way of splitting 16bit into two 8bits correct?

 
int lo_byte, hi_byte;
    long int get_value;
    UART_init();
        //printf("Enter any decimal number: ");

        get_value=UART_get_char_();  

    lo_byte = get_value & 0xFF;
    hi_byte = get_value >> 8;
 

2. How to send this Hex values into the I2C send program? Can a variable be assigned and then be used to transfer to SSPBUF?
like 
SSPBUF=lo_byte; 

 
Thanks in advance
#15
pcbbc
Super Member
  • Total Posts : 1188
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/05/27 08:42:53 (permalink) ☄ Helpfulby Abhishek ms 2019/06/17 01:17:21
+3 (3)
Your way of splitting is correct, IF get_value contains a 16 bit value. Unfortunately it does not, because UART_get_char can only ever return 8-bits from the UART - as already explained. Call UART_get_char twice to get two bytes and then combine them (or just read into lo_byte and hi_byte directly).

You really need to get to grips with how data is stored in the computer, in groups of 8 bits = 1 byte, representing values 0 to 255. And then how it is represented when displayed - which is completely different. For example in binary, hex, decimal or whatever. Those representations are usually in ASCII where every character of the representation also takes one byte. Usually these representations take more space than the real value. For example a byte takes two characters in hex (00 to FF) or 1 to 3 characters in decimal (0 to 255].
#16
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/06/17 01:47:22 (permalink)
0
I am very sorry to all, that it took me this long to respond. I have been given additional responsibilities to handel apart from this inn which I was very busy all these days.
 
I have been trying a few different methods to convert an integer into it's Hex equivalent. None have seen success, the itoa function does the job perfectly only when the integer value is feed directly to the function but gives the ASCII equivalent when fed through a variable.
 
I tried it integrating with I2C function, there is no Acknowledgement being received which leads me to belive that it is not working.
I have attached the c files of UART alone and UART integrated into I2C.
 
Thanks in advance.

Attachment(s)

Attachments are not available: Download requirements not met
#17
ric
Super Member
  • Total Posts : 23183
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How to transmit and read a 16 bit data using UART? 2019/06/17 02:20:11 (permalink)
+2 (2)
You totally forgot to mention what data you tested with, and what you got.
I can see in your code that you still don't really understand bytes, chars and integers.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#18
pcbbc
Super Member
  • Total Posts : 1188
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: How to transmit and read a 16 bit data using UART? 2019/06/17 02:54:49 (permalink) ☄ Helpfulby Abhishek ms 2019/06/20 03:07:02
+1 (1)
Abhishek msI have been trying a few different methods to convert an integer into it's Hex equivalent. None have seen success, the itoa function does the job perfectly only when the integer value is feed directly to the function but gives the ASCII equivalent when fed through a variable.

Sorry, this is nonsense.

itoa always converts a value to its ASCII equivalent (in the supplied radix).  It matters not a jot if you code a constant:
itoa(buf1, 0x42, 16);

or a variable:
int lo_byte = 0x42;
itoa(buf1, lo_byte, 16);


You seem very confused between the representation of values in memory - which are stored in one or more, usually consecutive, bytes - and their human readable representations in ASCII - which may be displayed in binary, decimal, hex, or any number of other ways.

One thing that looks like it might be causing you problems is that your function UART_get_char is returning you a signed char.  That means if the top bit is set, it will represent a negative number.  That will cause you all kinds of issues when you get to:
   int lo_byte;
    lo_byte=UART_get_char​();
    lo_byte= (char)lo_byte;

Because the sign bit will be extended to the full width of the integer variable.

So let's, say the value you read from the serial port is 0x0180.
The low byte will be read first, 0x80, which is -128 in two's compliment signed representation.
Then when you assign it to lo_byte (int) it will become 0xFF80 (1 of sign bit duplicated into high byte).
Then you will read the high byte, 0x01, which has a zero sign bit.
So when you assign that to hi_byte (int) it will become 0x0001 (0 of sign bit duplicated into high byte).

Probably what you want to code is more like:
   int lo_byte, hi_byte;

    lo_byte=(unsigned char)UART_get_char​();
    hi_byte=(unsigned char)UART_get_char​();



Or you could code functions, which is probably better if your 2 byte always represent a single value.  Holding a single 16-bit value in separate bytes is not useful if you want to process or display them as a single value later:
#include <stdint.h>

uint16_t UART_GetUInt16()
{
    uint16_t lo = (unsigned char)UART_get_char​();
    uint16_t hi = (unsigned char)UART_get_char​();
    return (hi << 8) | lo;
}

int16_t UART_GetInt16()
{
    return (int16_t)UART_GetUInt16();
}

...now you have functions to read either unsigned or signed values directly from the UART.
#19
ric
Super Member
  • Total Posts : 23183
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How to transmit and read a 16 bit data using UART? 2019/06/17 03:04:56 (permalink) ☄ Helpfulby Abhishek ms 2019/06/20 03:06:57
+2 (2)
Just avoid all that faffing around and define hi_byte, lo_byte, lo, hi all as "unsigned char".
None of those variable ever hold more than 8 bits.
 
Abhishek ms, to avoid future confusion, never use "char" to hold numbers. Always used "signed char" or "unsigned char" so you know what you're getting.
 
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5