Question

I have been trying to display floating point value using printf function using serial port of ATmega8 but instead of displaying floating point value, '?' character is displayed. The output is

Float: ?

Here is the code

#include <stdio.h>
#include <float.h>
#include <avr/io.h>

int printCHAR(char character, FILE *stream) 
{
    while(!(UCSRA&0x20));
    UDR=data;
    return 0;
}
FILE uart_str = FDEV_SETUP_STREAM(printCHAR, NULL, _FDEV_SETUP_RW);

int main(void)
{
    float fl = 1.3;
    stdout = &uart_str;         
    UCSRB=0x18; // RXEN=1, TXEN=1 
    UCSRC=0x06; // no parit, 1-bit stop, 8-bit data
    UBRRH=0;
    UBRRL=71;     //9600 baud rate
    while(1)
    {               
        printf("\r\nFloat: %f",fl);
    }
}
Was it helpful?

Solution

By default, the minimalistic printf library is used, which doesn't support floating point numbers and results in a "?" as a placeholder for the value. You have to tell the linker to use the floating point library.

For example (from GNU makefile)

PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min

You have to use the floating point version like so:

PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt

Depending on your base makefile, there should already be a section like this:

# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB = 
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)

Just uncomment the line containing PRINTF_LIB_FLOAT.

EDIT:
If you use AvrStudio4 without a custom makefile do this:

  1. use Project - Configuration
  2. select icon ("libraries")
  3. highlight "libm.a" and add to the right panel
  4. do the same for "libprintf_flt.a"
  5. under 5th icon "custom"
  6. select "[Linker]" optins
  7. type in "-Wl,-u,vfprintf" and [add]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top