Senin, 09 November 2015

Belajar Bahasa GCC

PART 1
Gnu Compiler Collection merupakan sebuah project compiler berbasis open source untuk beberapa bahasa pemrograman. Karena sifatnya yang "terbuka" inilah membuat pengembang bahasa pemrograman untuk microcontroller memilih bahasa C yang digabungkan dalam environment GCC, sebagai bahasa pemrogramman pada beberapa compiler seperti WINAVR atau TOOLCHAIN.

Kali ini akan kita bahas GCC yang digunakan paling umum untuk menyusun script dari pemrogramman AVR yang digunakan umum pada AVR STUDIO yatu WINAVR. Atmel sebagai produsen microcontroller AVR memiliki beberapa kerjasama dengan bahasa pemrograman lain seperti IAR akan tetapi banyak juga yang memilih versi gratisnya dengan menginstall plugin WINAVR. Pola pemrograman dari winavr umumnya seperti berikut :


HEADER


#define F_CPU 4000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include "coba.h"

uint8_t jam,menit,detik,show;

#define hidup PORTB|=_BV(PB3)



Pada  bagian header ini dinyatakan beberapa syntax yang berhubungan dengan pre-processor (#define),  variabel global serta  "include" yang merupakan rujukan compiler untuk menyertakan file-file eksternal. mari kita bahas satu persatu.


#define nama kondisi

Setelah #define terdapat  dua buah kalimat yang dipisahkan dengan spasi. Kalimat sebelah kiri merupakan rujukan sedangkan sebelah kanan merupakan proses yang dilakukan. Seperti contoh diatas maka dapat diartikan bahwa setiap syntax yang ditulis sebagai "nama" akan berubah menjadi "kondisi", contoh lain #define F_CPU 4000000UL berarti setiap syntax pada script yang berisikan "F_CPU" maka akan digantikan dengan "4000000UL" .

Jika ditulis seperti ini #define hidup PORTB|=_BV(PB3) maka setiap kita menulis  " hidup; " pada syntax maka akan terjadi kejadian pada port B3 akan menjadi "high" atau kalau dikasi LED akan menyala. Kenapa? karena syntax hidup telah diartikan sebagai syntax PORTB|=_BV(PB3) yang merupakan syntax untuk menghidupkan port B3.

Berguna banget apabila kita menggunakan perulangan "kondisi" yang banyak sehingga menyingkat dalam penulisan dan mempermudah proses tracing atau debuging error(kesalahan) syntax serta jalannya dari program yang diinginkan.


#include "nama.file"

Bagian ini untuk melakukan penyertaan compiling kepada file-file external. Contoh yang paling gampang adalah #include <avr/io.h> dimana compiler akan menyertakan directory pada instalasi WINAVR pada folder "include/avr" . File io.h merupakan file yang berisikan definisi port input output yang disesuaikan dengan jenis IC microcontroller yang digunakan. Include yang lain juga sangat berguna dan disesuaikan dengan kebutuhan, contohnya delay.h yang berhubungan dengan delay, interrupt.h yang berhubungan dengan interupt, string.h yang berhubungan dengan operasi string dan lain sebagainya. Untuk itu dapat dibaca pada website WINAVR di : http://winavr.sourceforge.net.

Untuk file include yang menggunakan tanda petik merupakan penyertaan file lokal yang diletakkan di folder atau direktori yang sama dengan direktori project


int variabel;

Untuk menyimpan suatu nilai pada memory maka diperlukan pemesanan lokasi variabel terlebih dahulu. GCC memiliki cara dinamis untuk menempatkan memory sehingga memudahkan dalam penyusunan. Variabel ini tentunya harus diberitahukan jenisnya sehingga dapat dipesankan sesuai kebutuhan. Contoh dari type variabel yang sering digunakan adalah seperti berikut :

- unsigned : menyatakan kalau type variabel berupa 8 bit sehingga nilainya antara 0-255, sama seperti char
- int : integer, merupakan memory 16 bit memiliki nilai antara -32768 sampai + 32767

ada beberapa type integer yang dapat diambil dengan menggunakan #include <inttypes.h>

- uint8_t  : 8 bit
- uint16_t: 16 bit
- uint32_t: 32 bit

sebagai contoh kita akan menyompan data karakter huruf, cukup dengan menggunakan unsigned char atau char saja karena karakter ascii merupakan data dengan lebar 8 bit. Sedangkan untuk perhitungan timer 16 bit maka sebaiknya menggunakan uint16_t yang memiliki lebar data 16 bit dan selalu bernilai positif.


PART 2
Bagian kedua dari tutorial akan membahas susunan scipt GCC yang digunakan sebagai bahasa pemrogramman microcontroller. Setelah sebelumnya kita membahas bagia header, maka sekarang kita bahas mengenai "function". Dalam bahasa C  semua kode dieksekusi berada dalam suatu function. Function adalah sebuah blok yang mempunyai nama  yang melakukan tugas dan kemudian akan mengembalikan kontrol ke pemanggil. Perhatikan bahwa bahasa pemrograman lain mungkin membedakan antara "function", "subroutine", "subprogram", "procedure", atau "metode" -  sedangkan dalam C hal ini semuanya sama dan bernama function.  Array dalam Bahasa C  dapat didefinisikan sebagai jumlah lokasi memori, yang masing-masing dapat menyimpan tipe data yang sama dan yang bisa menjadi referensi melalui nama variabel yang sama.


FUNCTION

Sebuah function sering dieksekusi (dipanggil) beberapa kali, dari beberapa tempat yang berbeda, selama eksekusi dari sebuah program. Setelah menyelesaikan subrutin, program ini akan bercabang dan kembali ke titik setelah dimana function ini dipanggil. Function adalah alat pemrograman yang kuat yang merupakan salah satu kelebihan bahasa C.


Secara umum pada pemrograman microcontroller berbasis GCC - Winavr, pola function paling utama adalah seperti berikut:


int main(void)

{  
  uint8_t a;
  DDRA  |= (1<<PA6)|(1<<PA7); //port yg digunakan PA6 & PA7  
  a=100;
  while(1)

   {    
    
  a=200;
    }
   
   return 0;

  }

loading...

function yang bernama main() merupakan function utama dimana awal dari program microcontroller dimulai. Function ini sebaiknya diberikan tipe data yang akan di kembalikan (return) karena beberapa compiler menanggap semua function itu sama. Jika tidak diberi type maka di depan main diberikan tanda void. Trus kenapa di dalam kurung terdapat void juga ? perhatikan jenis function berikut ini.




void coba_fungsi_1(void)

{  DDRA  |= (1<<PA6)|(1<<PA7);
//isi fungsi bebas ................
}


 int coba_fungsi_2(int var_a,  int var_b  ) 
 {
int var_c;

var_c = var_a + var_b ;
   
return (var_c);
   
  }
 
function yang berisikan kata-kata void berarti bahwa type dan variabel dari function tidak digunakan. Bandingkan dengan contoh function yang ke dua yang bertype integer dengan 2 buah variabel didalam kurung, yang jika dipanggil menggunakan perintah seperti berikut :


int main(void)

{  

int output;

 //panggil function1

    coba_fungsi_1();

  //panggil function2

   output = coba_fungsi_2(5, 3);


 // nilai dari variabel output =  8


  }



ARRAY

Array adalah penamaan kolektif yang diberikan kepada sekelompok data pada memory dalam jumlah yang sama. Jumlah yang sama ini contohnya bisa berupa nilai dari 100 siswa, jumlah kursi di rumah, atau gaji dari 300 karyawan atau usia dari 25 orang siswa. Jadi array adalah kumpulan elemen yang sama. Biasanya array dari banyak karakter disebut sebagai "string" array. Semua elemen dari setiap array yang diberikan harus dari jenis yang sama semisal kita tidak bisa memiliki sebuah array dari 10 buah nomor , yang 5 bertipe integer dan 5 sisanya bertipe uint8_t.

Contoh array yang sering dipakai dalam project-project di www.aisi555.com adalah array untuk data teks pada project led matrix "love hurt".



const char love[5]  =

{

0b0011110,

0b0100001,

0b1000010,

0b0100001,

0b0011110



};


const char L[5]  ={0x7f, 0x7f, 0x40, 0x40, 0x20}; 

const char O[5] ={0x3e, 0x7f, 0x41, 0x41, 0x3e};


char isinya[5],hasilnya[10];


const char creature[]={0x4e, 0x31, 0x35, 0x31, 0x4e}; 

uint8_t EEMEM tengkorak[5]= {0x1e, 0x75, 0x61, 0x75, 0x1e}; 




Dapat dilihat bahwa array memiliki nilai yang dapat di inisialkan terlebih dahulu atau nilainya kosong. Besar dari data yang dipesan untuk array sebaiknya di tentukan namun jika datanya seragam dapat juga dikosongkan. Array ini dapat kemudian dipindahkan ke dalam variabel lain ataupun di ubah nilainya.




int main(void)

{


  
//memindahkan data dari data yang sudah ada ke memory lain
 isinya[0]=creature[0]
 isinya[1]=creature[1];   
 isinya[2]=creature[2];
 isinya[3]=creature[3];   
 isinya[4]=creature[4];


//merubah data dari array secara sengaja

love[4]=0b0001100;


}





Jadi perlu diperhatikan ukuran dan jenis dari array yang akan dipindah-pindah haruslah sesuai.


PART 3
Setiap bahasa pemrograman memiliki suatu proses yang dinamakan "conditonal statement". Yang dimaksud sebagai contional statement adalah percabangan dimana terdapat beberapa pilihan jalannya program sesuai dengan kondisi yang terjadi.









Sementara itu pengulangan atau looping adalah proses pengulangan dari suatu perintah dimana bisa diberikan sebuah atau lebih kondisi yang menyebabkan pengulangan atau looping akan berhenti. Secara flowchart dapat digambarkan seperti berikut:

for.gif (383�402)



Kondisi Percabangan
Dalam bahasa C terdapat beberapa kondisi percabangan yang sering kita temui. Kita akan bahas satu persatu dengan contoh-contoh yang sering dipakai pada project di blog ini.

IF



if(kondisi == 1)
{
  //script 1

}

else if(kondisi == 3 || kondisi == 4)
{
  //script 2

}
 else if(kondisi <= 10 && kondisi >5)
{
   //script 3

}

else
 {   

 //script kondisi terakhir

}



Ada yang perlu diperhatikan pada percabangan yaitu selalu ada kondisi pembanding. Kondisi pembanding yang terdapat pada bahasa C adalah:


Pembanding sederhana:

==         Sama dengan

!=         Tidak sama dengan

<           Kurang dari

>           Lebih besar dari

<=         Kurang dari atau sama dengan

>=         Lebih besar dari atau sama dengan


Pembanding logika :

Hal ini dapat menggabungkan pembanding untuk mendapatkan logika yang lebih kompleks

&&         Dan (and)

||             Atau (or)



secara umum proses pencabangan IF .. ELSE  atau   IF .... ELSE IF ....ELSE membandingkan satu kondisi dengan kondisi yang lain , dan dapat juga menggabungkannya dengan tambahan pembanding logika. Untuk pencabangan IF .... ELSE IF ...dst .. yang terdiri dari banyak kondisi ELSE IF maka pencabangan akan menjalankan perintah pada kondisi yang benar kemudian mengabaikan yang lainnya. Perlu diingat jika eksekusi dari pencabangan mengikuti urutan atas ke bawah sehingga penempatan dari statement kondisi sangat penting.


SWITCH

Pola pencabangan yang lain adalah metode switch case seperti pada contoh berikut :


ISR(USART_RX_vect)



 char databyte;

 databyte = UDR; 



     switch (databyte)       

  {
     

    case 0xD : {  

             kirim_text(menu) ;

              break; }

    case '1' : {  

                     PORTB ^=(1<<0);

                     break; }

    case '2' : {

            
             PORTB ^=(1<<1);


                break; }

    default :{   
              PORTB |=(1<<1);
              break;}
  }  

}

Ketika mendefinisikan ekspresi kondisi yang hasilnya akan mengarah pada pelaksanaan program yang spesifik dan umumnya berjumlah banyak maka dapat menggunakan "switch".  Hasil yang berbeda tercantum dalam tiap tubuh "case" dari pernyataan switch dan setiap case memiliki eksekusi sendiri. Tubuh pernyataan switch dibatasi dari pembukaan ke penutupan kurung  kurawal: "{"   "}" dan jika memerlukan eksekusi tunggal maka diberikan perintah terminasi "break".  Sintaks dari kondisi switch seperti berikut :


switch(Expression)
{
    case Choice1:
        Statement1;
    case Choice2:
        Statement2;
    case Choice-n:
        Statement-n;
}






PENGULANGAN / LOOPING 
Pengulangan membantu program untuk menghemat penulisan pada urutan syntaxnya dengan memberikan kondisi keluar tertentu. Loop yang paling dasar adalah for(;;), yang memiliki 3 buah isian didalamnya berupa "kondisi awal" ; "kondisi keluar" ; "proses update" ; . Jika for tanpa isian seperti contoh for ( ; ; ) maka akan menciptakan looping tidak berhingga yang tak akan pernah selesai.


void proses (void) 

{
int a;


for(a=0; a < 10 ; a++) 
   {
      PORTB = a;
      PORTC = (10 - a) ;
   }

}


script diatas memiliki penjelasan bahwa nilia a berawal pada angka 0, akan diulang terus bila nilai a lebih kecil dari 10  sedangkan kondisi update nilai a ditambah 1 tiap pengulangan. Jadi nilai a bermula dari 0 diteruskan menuju 1,2,3,4,5,6,7,8,9  kemudian pada saat nilai a mencapai nilai 10 maka loop akan  selesai.


Jenis looping yang lain memiliki pola yang sama yaitu while(condition) {  }  dan do { } while(condition). Kondisi keluar dari loop ditentukan pada awal atau akhir namun memiliki pola yang sama yaitu kondisi awal dan akhir harus dirubah berdasarkan pengulangan atau kondisi luar ,seperti contoh berikut :




int a;
a=0;
while(a < 10)
{
  PORTB=a;
  PORTC=(10-a);

   a++;
}
a=0;


do
{
PORTB=a;
a++;
}
while(a <10)


while(bit_is_set(PIND, PIND3) )
{

PORTB|=_BV(PB3);

}


Ingat jika kondisi dari variabel harus di inisialisasikan terlebih dahulu sehingga tidak menimbulkan kesalahan dan warning saat dicompile. Contoh yang terakhir menunjukkan bahwa kondisi looping akan berhenti jika ada perubahan nilai dari luar , dalam hal ini nilai logika biner dari port microcontroller PIND3 .


SELAMAT BELAJAR











sumber:
www.aisi555.com

Tidak ada komentar:

Posting Komentar