display decimal to LCD

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

display decimal to LCD

跳至解决方案
3,931 次查看
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

标签 (1)
0 项奖励
回复
1 解答
1,169 次查看
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 项奖励
回复
6 回复数
1,170 次查看
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 项奖励
回复
1,169 次查看
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 项奖励
回复
1,169 次查看
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 项奖励
回复
1,169 次查看
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 项奖励
回复
1,169 次查看
gustavod
Contributor III

 

Thanks for the advice Mac.

 

Regards,

Gustavo

0 项奖励
回复
1,169 次查看
gustavod
Contributor III

Hi Mac,

 

Great idea of ​​supporting sign values.

 

Best regards,

Gustavo

0 项奖励
回复