display decimal to LCD

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

display decimal to LCD

Jump to solution
3,591 Views
broady20
Contributor I

I'm trying to convert a HEX number to a deciaml number so that I can display it onto the LCD. I can display everything I want on the the display but my number is in HEX. My hex number is coming from a routine that converts the value stored in ATD0DR0H. The value stored there is (I think) binary, so what every is easier binary to deciamal or Hex to decimal, I need to convert to deciamal. I'm using CodeWarrior I have attached the code that I have so far. Thanks to anyone that helps me

Heath

Labels (1)
0 Kudos
1 Solution
829 Views
bigmac
Specialist III

Hello, and welcome to the forum.

 

It is more straight forward to convert a binary value to decimal numeric ASCII characters, assuming the LCD is compatible with these.  For simplicity, the following code snippet assumes a 16-bit unsigned binary value, and generates up to five digits, right aligned.

 

void disp_decimal( word val){   char buf[6];  // Temporary buffer for numeric data   int i;   // Fill buffer with spaces   for (i = 0; i < 5; i++)      buf[i] = ' ';   buf[5] = 0;   // Null termination for data   // Convert binary value to decimal ASCII   for (i = 4; i >= 0; i--) {      buf[i] = (val % 10) + '0';      val /= 10;      if (val == 0)  break;   }   lcd_puts_String( buf);  // Send string data to LCD}   

 

Regards,

Mac

 

 

View solution in original post

0 Kudos
6 Replies
830 Views
bigmac
Specialist III

Hello, and welcome to the forum.

 

It is more straight forward to convert a binary value to decimal numeric ASCII characters, assuming the LCD is compatible with these.  For simplicity, the following code snippet assumes a 16-bit unsigned binary value, and generates up to five digits, right aligned.

 

void disp_decimal( word val){   char buf[6];  // Temporary buffer for numeric data   int i;   // Fill buffer with spaces   for (i = 0; i < 5; i++)      buf[i] = ' ';   buf[5] = 0;   // Null termination for data   // Convert binary value to decimal ASCII   for (i = 4; i >= 0; i--) {      buf[i] = (val % 10) + '0';      val /= 10;      if (val == 0)  break;   }   lcd_puts_String( buf);  // Send string data to LCD}   

 

Regards,

Mac

 

 

0 Kudos
829 Views
gustavod
Contributor III

Hi BigMac,

 

Great code.

Based on your idea we made a modification for microcontrollers without hardware divider:

 

void disp_decimal(INT16U val, CHAR8 *buff){   INT16U backup;   INT8U i;      // Fill buffer with spaces   for (i = 0; i < 5; i++)    {      *(buff + i) = ' ';   }      // Null termination for data   *(buff + i) = 0;   // Convert binary value to decimal ASCII   for (i = 4; i >= 0; i--)    {      backup = val;      val /= 10;      *(buff + i) = (backup - (val*10)) + '0';            if (val == 0)  break;   }}

 

We made same modifications on the buffer creation too. You can use like this.

 

char buff[6];

disp_decimal(12345, buff);

 

And use the generated string for everything.

 

Best regards,

Gustavo

 

 

 

0 Kudos
829 Views
bigmac
Specialist III

Hello Gustavo,

 

Yes, there are many variations on this theme.

 

Irrespective of whether a hardware divider is available, your approach to deriving the remainder of each division is very likely to be more efficient.  This is because you have a single explicit division only.  With my previous aproach, there is likely to be two divisions - an implicit one for the '%' operator implementation, plus the explicit one.  But this will depend on the compiler optimisation process.

 

I notice that the local variable is declared as type INT8U, presumably unsigned.  I might have expected this would need to be a signed type for the second decrementing loop to exit, when there is a 5-digit result.

 

If using a buffer that is external to the conversion function, it may provide more flexibility and efficiency if the buffer initialisation also occurs outside the function.  This is especially so if the function is called to "fill in the blanks" of a larger string.  For example -

 

void disp_temp( int temp){  char buffer[] = "Temperature:    0 C";  // Initialise local variable  conv_decimal( temp, &buffer[11]);  LCD_puts( buffer);}

 

 The following is a proposed adaption to allow the handling of a signed value.  In this case, the local variable 'i' can be unsigned, since the loop exit does not require a negative value.

 

void conv_decimal(INT16 val, CHAR8 *buff){   INT16U backup;   INT8U i;   CHAR8 s = ' ';      // Fill buffer with spaces   for (i = 0; i < 6; i++) {      *(buff + i) = ' ';   }      // Null termination for data   *(buff + i) = 0;   if (val < 0) {      val = -val;      s = '-';   }   // Convert binary value to decimal ASCII   for (i = 5; i > 0; i--) {      backup = val;      val /= 10;      *(buff + i) = (backup - (val*10)) + '0';            if (val == 0)  break;   }   *(buff + i) = s;  // Sign character}

 

Regards,

Mac

 

0 Kudos
829 Views
bigmac
Specialist III

Hello,

 

I just noticed an inconsistency in the placment of the sign character, depending on whether the for-loop completes, or there is an early break.  The index variable 'i' needs to be decremented prior to either event.

 

   // Convert binary value to decimal ASCII   for (i = 5; i; ) {      backup = val;      val /= 10;      *(buff + i) = (backup - (val*10)) + '0';      i--;      if (val == 0)  break;   }   *(buff + i) = s;  // Sign character

 

Regards.

Mac

 

0 Kudos
829 Views
gustavod
Contributor III

 

Thanks for the advice Mac.

 

Regards,

Gustavo

0 Kudos
829 Views
gustavod
Contributor III

Hi Mac,

 

Great idea of ​​supporting sign values.

 

Best regards,

Gustavo

0 Kudos