Standard Library & String Formatting for AVR

Mathew Kevin July 10, 2017 4 Comments

Here in this article, I am planning to brief you through the Standard library of AVR-GCC. By the term “Standard Library” we mean the “Standard header” files like “stdio.h”, we commonly see in C programming language. Have you ever used String Formatting in ANSI C? Did you use Standard library functions? If you are familiar with C programming language, then you must be familiar with standard header files we write in the beginning of the program like “#include stdio.h“, “#include stdlib.h” , “#include conio.h” etc etc. The most important of all header files is the header file -which simply means “Standard Input Output header file”. It is by adding this header file, we make the compiler recognize and interpret standard library functions like “Scanf” (to get input) and “Printf” (to output to a device like display or pinter).

printf(“Hello! % d %f %c %s”,a,b,c,d);

Now I hope you have got some idea about what I’m going to tell. Before going deep into this article, I would like to show you some tutorials I have written before, which will be useful for you.

1. An Introduction to Atmega32

2. An Introduction to Atmega8

3.  Avr Studio Overview for Beginners

4. Avr Gcc Library – An Overview

Okay! Now I am going to show you an important difference between programming in C and for the Avr-Gcc.  In C programming, you just need to write the command printf(“Hello! % d %f %c %s”,a,b,c,d); to send these string of characters all together to the output device, like a display or a printer.The “printf()” function makes it easier for you. It takes care of the conversion portion.

In AVR studio there the end compiler is AVR-GCC framework. A header file named ‘stdio.h’ comes here too. The ‘printf()’ function prototype is defined there. But here it demands complete description of a routine to send a single character to the display device or a routine that will send a string of characters. The prototype of the routine must match with the return types and arguments as demanded by the end compiler. Else the function will malfunction or will not get compiled at all (resulting in error).

Now the complete code of the “printf()” and its core functions are quite big. It involves string formatting including the floating point conversation. The implementation of integer conversion is much smaller. So AVR Studio offers three flavors of the ‘printf()’! One implements moderate functionality of the string formatting (signed integer conversion), another low (only unsigned integer conversion), and the last one offers full functionality of that (including signed and unsigned floating point and same of that integer conversion). To use full or lower functionality, you’d have to request the compiler to compile those specific implementations. Otherwise, the unimplemented formatting would place a ‘?’ character in the formatted string. To do this you’d have to modify some settings. You’ll find it in this article.

Now let us see an example. I’m using a LCD display for this experiment. Use my circuit diagram I used previously in the post “Interfacing LCD display in 8 bit mode ”. In this interfacing circuit, I wrote a program to display a string of characters “Circuits Today” in the LCD. You may see the circuit and code as well. Now I’ll use a a modified version of the functions to send characters. Have a look.

//---------------------------------------------------------------------------
#include
#include
#include
#define DEL1 10
#define DEL2 40

#define DPORT PORTB
#define CPORT PORTD
#define DPDDR DDRB
#define CPDDR DDRD
#define RS PD6
#define EN PD7
int LCD(char ch, FILE *fp); //this is the prototype of the routine
void LCDcmd(char ch);
void initLCD();
static FILE lcd_str= FDEV_SETUP_STREAM(LCD,NULL,_FDEV_SETUP_WRITE);
//The line above sets up a stream for formatted O/P

void LCDcmd(char ch) // Function to send commands to the LCD module
{ DPORT = ch;
CPORT = (1<<EN);
_delay_us(DEL1);
CPORT = (0<<EN);
_delay_us(DEL2);
if(ch==0x01||ch==0x02)
_delay_ms(2);
}

int LCD(char ch, FILE *fp)
{ DPORT =ch;
CPORT = (1<<EN)|(1<<RS);
_delay_us(DEL1);
CPORT = (0<<EN)|(0<<RS);
_delay_us(DEL2);
return 0;
}

void initLCD()
{ CPDDR = (1<<EN)|(1<<RS);
DPDDR = 0xff;
LCDcmd(0x38);
LCDcmd(0x0f);
LCDcmd(0x01);
LCDcmd(0x02);
}
int main()
{ stdout= @lcd_str;
initLCD();
printf(“Circuits Today”);
LCDcmd(0xc0);
printf(“Int: %d.%d.%d”,15,2,2012);
return 0;
}
//—————————————————————————————————————————————-

So that was how to use a “printf()” function. Similar would be for a “vfprintf()”. A “printf()” can be considered as “vfprintf(stdout,” ”,……)”. But wait. You can set up streams for communication to and use ‘printf()’ to send formatted string.
But what for Floating point conversion (that ‘%f’ stuff)? This function is fine for integer, character and strings. But if you put floating point or double conversion, it will put a ‘?’Character where a floating point number should have been displayed! To get the floating point to string conversion, you must configure the following settings in the AVR Studio:

So here are the settings to configure Avr-Gcc to display a floating point number:-

As shown in image, select “Libraries” from Project Options.

avr gcc floating point number

Add the libraries as shown in figure – libprintf_flt.a and libm.a

Now see the picture below and do as it says:-

Select “Custom Options” and apply the settings as shown in image.

avr gcc settings

After these settings, you’ll find this code is working too.

//----------------------------------------------------------------------------------------------------------------------------------------
int main()
{ stdout= @lcd_str;
initLCD();
printf(“Circuits Today”);
LCDcmd(0xc0);
printf(“Int: %3.2f.%d”,15.2,2012); // Note that this line includes
// A floating point conversion
return 0;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------

Any doubts? Post a comment here! I shall respond 🙂

Comments
  • Roy Fernandez
    April 11, 2012

    Thanks a lot for this, the source code and the screen shots were really helpful.

    • Rakesh
      July 9, 2012

      Thank you, for your appreciation!!

  • Harry
    April 3, 2012

    I think you meant “a floating point conversion,” instead of pint conversion, in the last code table.

    • jojo
      April 3, 2012

      @Harry

      It was a typo error 🙂 Corrected and thanks for notifying!

Leave a Reply to Rakesh Cancel reply

Your email address will not be published. Required fields are marked *