Printf dan Scanf USART pada AVR Studio 4 + AVR AVR GCC

Sumber: embedds.com/using-standard-io-streams-in-avr-gcc/

Mengatur Linker

WinAVR , AVR Studio atau AVR GCC secara default, linker option-nya di-set standard yaitu tanpa floating point conversion.

USART1

Jadi kita ingin mengirim string dengan basic integer number, maka gunakan minimized version. Maka gunakan linker option sebagai berikut.

-Wl,-u,vfprintf -lprintf_min 

Jika kita ingin fungsi untuk floating point maka gunakan standard option dengan floating point conversion:

-Wl,-u,vfprintf -lprintf_flt -lm

Untuk menambahkan linker option pada AVR Studio 4, maka buka project option à Custom Option , lalu tambahkan –Wl, -u, vprintf ke linker option seperti gambar di bawah ini:

avrstudio_linker_options-445x300

Kemudian buka tab Libraries dan tambahkan libprintf_flt.a dan libm.a karena float conversion membutuhkan math library.

avrstudio_linker_options_libraries-441x300

Hal ini juga berlaku untuk fungsi scan. Jika kita akan sering membaca data streams, maka masukan juga linker berikut.

Untuk minimized version:

-Wl,-u,vfscanf -lscanf_min

Untuk float version:

-Wl,-u,vfscanf -lscanf_flt –lm

Men-setting I/O Streams

Send

int USART0SendByte(char u8Data, FILE *stream)
{
   if(u8Data == '\n')
   {
      USART0SendByte('\r', 0);
   }
   //wait while previous byte is completed 
   while(!(UCSR0A&(1<<UDRE0))){};
   // Transmit data
   UDR0 = u8Data;
   return 0;
}

 

Receive

int USART0ReceiveByte(FILE *stream)
{
   uint8_t u8Data;
   // Wait for byte to be received
   while(!(UCSR0A&amp;(1&lt;&lt;RXC0))){};
   u8Data=UDR0;
   //echo input data
   USART0SendByte(u8Data,stream);
   // Return received data
   return u8Data;
}

 

Lalu tambahkan pula kode berikut.

FILE usart0_str = FDEV_SETUP_STREAM(USART0SendByte, USART0ReceiveByte, _FDEV_SETUP_RW);

 

Kita bisa mengatur untuk mengunakan stream data untuk menerima, mengirim, atau kedua-duanya tergantung dari parameter yang yang kita setting pada FDEV_SETUP_STREAM tadi.

read - _FDEV_SETUP_READ

written - _FDEV_SETUP_READ

read/written - _FDEV_SETUP_RW

Dalam C, stream data itu ada 3. Pada computer bentuk stream data ini digunakan untuk membaca keyboard – stdin (standard input stream), output ke layar – stdout (standard output stream) dan satu lagi output ke layar – stderr (standard error stream). Untuk itu kita perlu menginisialisasi standard stream yang akan kita gunakan sebagai berikut.

stdin=stdout=&amp;uart0_str;

Dengan demikian kita bisa menggunakan fungsi prinf() dan akan memudahkan kita dalam menggunakan usart.

Print Format

Sebelum kita menggunakanfungsi print seperti int fprintf(FILE*, const char *, ) kita perlu faham dulu format datanya. Untuk fungsi ‘printf’ terdiri dari.

fprintf_format

Jika menggunakan fungsi stream standard maka bentuknya printf(formatted string, arguments); fungsi ini memungkinkan kita untuk mengubah arguments yang kita masukan menjadi data string. Bentuk data yang diubah akan ditempatkan pada formatted string dengan cara mengawalinya dengan tanda “%”:

%[flag][leading][width].[precision][length]specifier

Setiap tag dapat diatur sesuai kebutuhan. Hal ini bisa banyak dicari pada tutorial bahasa C.

Flag can be:

space – that can usually is filled if number sign is present;

+ – forces to use plus/minus sign to positive/negative number;

– – left justifies result (default is right);

# – Used with o, x or X specifiers the value is preceded with 0, 0x or 0X respectively for values different than zero; Used with e, E and f forces output to contain a decimal point even if no digits would follow; Used with g or G the result is the same as with e or E but trailing zeros are not removed.

Leading – print a leading zero(ignored for negative numbers);

Width – minimum field of characters to be printed. Padded with spaces if result is shorted and truncated if longer. If * is used then it represents integer number that is taken from argument list.

Precision – represents number of digits after decimal point for double numbers. For integers this number shows the minimum number of digits to be printed. If number is shorter – leading zeros are added, if longer- it is truncated. It also can be specified as * and value taken from arguments.

Length – can be h, l, and L. used for argument compatibility where h – stands for short int, l – long int and L – long double.

Specifier – this is a mandatory specifier. It defines value type of corresponding argument:

  • c – character (eg. a, C, …);
  • i, d – decimal integer (eg 10, -23);
  • u – unsigned integer (eg. 100);
  • e, E – scientific format (eg. 1.2e01, 5E21);
  • f – decimal floating point (eg. -5.014);
  • g, G – shorter e or f (eg. -5.02, 5E2);
  • o, O – octal unsigned integer (eg. 457);
  • x, X – unsigned hexadecimal (eg. 1f8, FF4);
  • s – string of characters (eg. Hello);
  • p – pointer address;
  • n – associated argument points to int variable which holds current count of printed characters;
  • % – % followed after % prints character %.

Pada AVR GCC library stdio.h pada beberapa fungsi mungkin memiliki keterbatasan seperti beberapa tag atau specifiers tidak bekerja.

Testing I/O stream functionality

Berikut contoh penggunaan fungsi print (mengirim data usart) dan juga scanf() (menerima data usart).

#include <stdio.h>
#include <math.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define USART_BAUDRATE 9600
#define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
void USART0Init(void)
{
// Set baud rate
UBRR0H = (uint8_t)(UBRR_VALUE>>8);
UBRR0L = (uint8_t)UBRR_VALUE;
// Set frame format to 8 data bits, no parity, 1 stop bit
UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);
//enable transmission and reception
UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
}
int USART0SendByte(char u8Data, FILE *stream)
{
   if(u8Data == '\n')
   {
      USART0SendByte('\r', 0);
   }
//wait while previous byte is completed
while(!(UCSR0A&(1<<UDRE0))){};
// Transmit data
UDR0 = u8Data;
return 0;
}
int USART0ReceiveByte(FILE *stream)
{
uint8_t u8Data;
// Wait for byte to be received
while(!(UCSR0A&(1<<RXC0))){};
u8Data=UDR0;
//echo input data
USART0SendByte(u8Data,stream);
// Return received data
return u8Data;
}
//set stream pointer
FILE usart0_str = FDEV_SETUP_STREAM(USART0SendByte, USART0ReceiveByte, _FDEV_SETUP_RW);
int main (void)
{
//sample data
uint16_t u16Data = 10;
double fltData = 3.141593;
int8_t s8Data = -5;
uint8_t u8str[]="Hello";
uint8_t u8Data;
//Initialize USART0
USART0Init();
//assign our stream to standart I/O streams
stdin=stdout=&usart0_str;
//print unsignet integer
printf("\nunsigned int = %u",u16Data);
//print hexadecimal number
printf("\nhexadecimal unsigned int = %#04x",u16Data);
//print double with fprint function
fprintf(stdout,"\ndouble = %08.3f", fltData);
//print signed data
printf("\nsigned int = %d",s8Data);
//print string
printf("\nstring = %-20s",u8str);
//print string stored in flash
printf_P(PSTR("\nString stored in flash"));
//printing back slash and percent symbol
printf("\nprintf(\"\\nstring = %%-20s\",u8str);");
    while(1)
    {
    printf_P(PSTR("\nPress any key:"));
    //scan standard stream (USART)
    scanf("%c",&u8Data);
    printf_P(PSTR("\nYou pressed: "));
    //print scaned character and its code
    printf("%c; Key code: %u",u8Data, u8Data);
    }
}

 

Berikut hasil yang dicapture pada terminal serial.

printf_example_terminal_results

Program tersebut menggunakan variable float, maka kita terlebih dahulu perlu men-setting linker dengan setting floating point seperti yang telah kita bahas di atas. Fungsi printf juga bisa digunakan untuk menampilkan data pada LCD atau pada perangkat lainnya. Jika operasi stream tidak terikat pada hardware tertentu – fungsi stream yang sama bisa kita definisikan pula untuk hardware berbeda. Kita bisa mengirim data yang sama menggunakan USART atau LCD jika perlu – hanya satu fungsi hardware yang perlu diubah.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s