1

我想在 LCD 上显示浮点值。我使用 avr5.1 编译器并使用函数 snprintf 将浮点值转换为 ASCII。但它给出了 Proteus 的输出“?”。

这是我正在使用的代码;我还包括了 printf_flt 库:

temp1=ADCH;
// FOR MEASURING VOLTAGE
temp=(temp1*19.53)*2.51;                
LCD_goto(1,1);                                      
snprintf(buffer,6, "%2.2f", temp);  
lcd_data1(buffer);  
lcd_data1("mV");
percent=(temp-11500);
LCD_goto(2,2);
snprintf(buffer1,4, "%2.2f", percent); 
lcd_data1(" ");
lcd_data1(buffer1);
lcd_data1("%");     

这是输出的图片:

我的代码的输出

4

1 回答 1

1

许多开发工具具有多个版本printf和相关功能,支持不同级别的功能。浮点数学代码庞大而复杂,因此包含未使用的功能会浪费大量代码空间。

有些工具会自动尝试找出需要包含哪些选项,但有些不是很好,有些只是要求程序员printf使用命令行参数、配置文件或其他类似方式明确选择适当的版本。可能需要使编译器包含支持说明符的 printf 相关函数的版本%f,或者使用其他一些格式化输出的方法。我自己的首选方法是将值转换为缩放整数(例如,期望值的 100 倍),然后编写一个输出数字的方法,首先是最不重要的,并在输出一些数字后插入一个句点。就像是:

uint32_t acc;

uint8_t divMod10()
{
  uint8_t result = acc % 10;
  acc /= 10;
}

// output value in acc using 'digits' digits, with a decimal point shown after dp.
// If dp is greater than 128, don't show decimal point or leading zeroes
// If dp is less than 128 but greater than digits, show leading zeroes
void out_number(uint8_t digits, uint8_t dp)
{
  acc = num;
  while(digits-- > 0)
  {
    uint8_t ch = divMod10();
    if (ch != 0 || (dp & 128) == 0)
      out_lcd(ch + '0');
    else
      out_lcd(ch);
    if (--dp == 0)
      out_lcd('.');    
  }
}

由于 LCD 模块可以配置为从右到左接收数据,因此以这种形式输出数字可能是一种有用的简化。请注意,我很少在小型微控制器上使用任何“printf”系列函数,因为像上面这样的代码通常更紧凑。

于 2014-10-21T21:48:57.393 回答