0

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);
    }
}
3
  • you really shold consider to avoid floating points on tiny controllers like AVRs since they are software emulated and require huge amount on program space and are rather inefficient on calculations. use proper scaled integer instead. Commented Mar 20, 2014 at 12:00
  • @vlad_tepesch I see. what about bigger microcontrollers like ATmega 128 and ATmega2560 ? Commented Mar 21, 2014 at 2:45
  • they are not really "bigger" just have more flash. please do not misunderstand me. if the floating point code does not have any runtime performance requirements and overall code size is not critical just use them to save development time. but i personally try to avoid them since AVRs mostly do simple measurement and control tasks that do not require very complex math so that the used math is easy to port to fixed point calculations. Commented Mar 21, 2014 at 6:45

1 Answer 1

1

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]
Sign up to request clarification or add additional context in comments.

4 Comments

I could not find the GNU makefile location. Where is this file located ?
@avr_rookie: What is you programming environment? Are you using Avr Studio (which version)? Or WinAVR + external editor?
I am using AVR Studio 4 and mostly use ATmega128 and ATmega2560 but for this I am using Atmega8. Since I come across floating point data-types most of the time, I want to output floating point data although most of the time I scale them to integer.
@avr_rookie: See the edit in my post regarding instruction for AvrStudio 4.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.