JAM DIGITAL DENGAN
BAHASA C
Oleh:
Budhy Sutanto

Gambar 0. Tampilan jam digital yg sudah jadi pada sistem
experiment
Bahasa
Assembler merupakan bahasa pemrograman tingkat paling rendah, hanya mengenal
instruksi-instruksi paling dasar mikrokontroler, ditambah dengan beberapa
perintah untuk mengatur memori secara sederhana. Bahasa pemrograman ‘satu
tingkat’ di atas Asembler adalah bahasa C yang sangat fleksible, dipakai untuk
membangun Windows, tapi bisa juga dipakai untuk rancang bangun peralatan dengan
mikrokontroler.
C asalnya
dirancang sebagai bahasa pemrograman untuk membangun sistem operasi UNIX pada
komputer DEC PDP-11, sekitar awal tahun 1970-an. Bahasa ini berkembang secara
pesat, pada tahun 1983, American National Standards Institute (ANSI) membentuk
komite kerja dengan tugas khusus membakukan bahasa C sebagai bahasa pemrograman
yang tidak tergantung pada jenis komputer. Hasil kerja komite tersebut merupakan
pedoman baku untuk bahasa C, dan C compiler yang
dibangun atas dasar pedoman tersebut disebut sebagai ANSI-C.
Semua C compiler yang ada kini kebanyakan adalah ANSI-C,
tapi masing-masing mempunyai variasinya tersendiri, dilengkapi dengan
sarana-sarana untuk memudahkan pemakaian C pada komputer tertentu. Dalam
hal ini dikenal Turbo C, Borland C++, Visual C dan lain sebagainya, semuanya
merupakan C Compiler yang banyak dipakai pada IBM-PC, tentu saja hasil akhir
dari semua C Compiler tadi adalah kode mesin untuk prosesor IBM-PC (8086, 80286,
80386, 80486 dan Pentium).
Tapi bahasa C untuk keperluan rancang bangun peralatan yang
memakai mikrokontroler tentu saja tidak memerlukan sarana-sarana tambahan
secanggih C Compiler yang dipakai dalam IBM-PC, dan hasil akhirnya harus berupa
kode mesin untuk masing-masing mikrokontroler/mikroprosesor.
Artinya C Compiler untuk mikrokontroler MCS51 harus
menghasilkan kode mesin MCS51, C Compiler untuk MC68HC11 harus menghasilkan kode
mesin MC68HC11 pula.
Dengan pengertian di atas. C
Compiler untuk IBM-PC tidak bisa dipakai untuk mikrokontroler, dan masing-masing
jenis mikrokontroler mempunyai C Compiler tersendiri.
C Compiler untuk MCS51
Sejak akhir tahun 1980-an, telah banyak dibuat C
Cross-Compiler yang bekerja pada IBM-PC untuk MCS51, artinya C Compiler tersebut
bekerja di IBM-PC tapi kode mesin yang dihasilkan bukan untuk IBM-PC melainkan
untuk MCS51.
C Compiler
untuk MCS51 yang cukup dikenal antara lain adalah
Micro-C buatan Dunfield Development Systems, Franklin C buatan Franklin Software
Inc dan C51 buatan Keil Software, harga perangkat lunak tersebut tidak murah.
Yang menarik meskipun harganya mahal, Keil membagikan C51 produknya yang bisa
diminta lewat situs web http://www.keil.com, C51 gratis tersebut dibatasi hanya
bisa menghasilkan kode mesin MCS51 paling banyak 2 KiloByte.
Tapi untuk keperluan projek kecil-kecil yang memakai AT89C2051 batasan memori
tersebut tidak merupakan masalah, karena memori-program AT89C2051 memang hanya
sebesar 2 KiloByte.
Selain produk komersil tersebut di atas, ada pula C Compiler
gratis, yang dikenal sebagai SDCC – Small Device C Compiler.
Small Device C Compiler -
SDCC
SDCC, buatan Sandeep Dutta (sandeep@users.sourceforge.net),
sejak semula memang dibuat sebagai software gratis (freeware), kemudian project
mulia ini digabungkan dengan projek GNU, yakni projek ramai-ramai insan Internet
yang melahirkan Linux. Dengan demikian, kini program
SDCC bisa diambil pada situs http://sdcc.sourceforge.net.
Dalam rancangannya, SDCC
dipersiapkan untuk berbagai macam mikroprosesor / mikrokontroler, hal ini sesuai
dengan sifat bahasa C yang mudah diadaptasikan ke berbagai macam prosesor.
Sampai saat ini, SDCC sudah bisa dipakai untuk mikroprosesor Z80, mikrokontroler
MCS51, dalam waktu dekat akan segera bisa dipakai untuk mikrokontroler AVR
buatan Atmel, dan mikrokontroler PIC buatan MicroChip, dan beberapa prosesor
lainnya akan segera menyusul.
Hal ini membuat SDCC menjadi
sangat menarik. Setelah terbiasa memakai SDCC untuk projek-projek dengan
MCS51, kelak satu saat bermaksud memakai mikrokontroler AVR karena memerlukan
mikrokontroler yang kemampuannya lebih, maka tidak banyak hambatan untuk beralih
prosesor, bahkan program-program yang sudah dikembangkan untuk MCS51 dengan SDCC,
dengan sedikit perubahan bisa dipakai di sistem yang memakai AVR.
Digital Clock dengan SDCC
Artikel ini tidak dimaksud
untuk mengajarkan bahasa C, tapi hanya sekedar mengenalkan C untuk
mikrokontroler dengan contoh yang sesungguhnya.
Artikel Digital Clock - Ilhami Prinsip Dasar
Microcontroller dalam Komputek edisi No. 175 Minggu ke IV Juli 2000 (http://alds.stts.edu/DIGITAL/DigitalClock.htm),
merupakan contoh pemakaian AT89C2051 yang sangat sederhana.

Gambar 1 Rangkaian Digital Clock
Program C berikut merupakan saduran langsung dari
program CLOCK.ASM
yang ditulis dalam bahasa Assembler MCS51, dipakai untuk mengendalikan Digital
Clock dengan rangkaian seperti terlihat dalam Gambar
1, cara kerjanya dibahas dalam artikel di atas.
Program tersebut ditulis dengan program editor
biasa, bisa pakai
EDITOR.COM dalam DOS atau
NotePad.EXE
dalam Windows, kemudian disimpan dalam file dengan nama
CLOCK.C.
Selanjutnya pada
DOS
prompt diberikan perintah
SDCC CLOCK.C, perintah ini
akan menghasilkan banyak file, semua dengan nama yang
dimulai dengan CLOCK.
Dari sekian banyak file tersebut terdapat
CLOCK.IHX,
file ini merupakan file berisikan kode mesin MCS51 (object file) dengan format
Intel Hex yang siap diisikan ke dalam PEROM dari AT89C2051.
Program 1 – Digital Clock sederhana
dengan C
01:/************************************************************\
02: Digital Clock
03:\************************************************************/
04:#include <AT89X51.h>
05:char Pencacah20;
06:char Detik;
07:char Menit;
08:char Jam;
09:char Ruas[4];
10:sbit at 0xB5 TombolJam; // P3.5
11:sbit at 0xB7 TombolMenit;
// P3.7
12:
13:// ****** Membentuk ruas-ruas angka untuk
ditampilkan ******
14:void Ruas2Digit (unsigned char c, unsigned char
pos){
15: code char KombinasiRuas[] =
{0xC0,0xF9,0xA4,0xB0,0x99,
16:
0x92,0x82,0xF8,0x80,0x90};
17: Ruas[pos++] = KombinasiRuas[c/10];
18: Ruas[pos] = KombinasiRuas[c%10];
19: }
20:void PerbaruiTampilan (void){
21: Ruas2Digit(Jam,0);
22: Ruas2Digit(Menit,2);
23: }
24:// ****** Waktu tunda penyalaan 1 digit angka
******
25:void TungguSebentar() { // tunggu selama 1,5
mili-detik
26: //th0:tl0 diisi dengan -1500,
27: //sebagai pencacah count-up 1500 pulsa
kemudian
28: //(=1500 mikro-detik) pencacah melimpah
menjadi 0 (TF1=1)
29: TH1 = (-1500/256)-1;
30: TL1 = (-1500%256);
31:
32: TF1 = 0; //Timer Flag 1
di-nol-kan
33: TR1 = 1; //Timer 1 mulai men-cacah
34: while (!TF1); //Tunggu sampai TF1
menjadi 1
35: }
36:/***************************************************************\
37:* Bagian Utama
*
38:* Tugas Utama AT89C2051 menangani Sistem
Tampilan 7 ruas, dan *
39:* menjalankan rutin
ScanDisplay tanpa berhenti. *
40:* *
41:* Interupsi Timer terjadi setiap 50 mili detik
sekali, saat itu *
42:* AT89C2051 meninggalkan sebentar Bagian Utama
ini, untuk mengu *
43:* rus untaian
pencacah Menit dan pencacah Jam. *
44:\***************************************************************/
45:void main (void){
46: Pencacah20=20; //Nilai awal
Pencacah20
47: Jam=Menit=Detik=0; //Mulai dari Jam/Menit
0
48: PerbaruiTampilan();
49:
50: //th0:tl0 diisi dengan -50000,
51: //sebagai pencacah count-up 50000 pulsa
kemudian
52: //(=50000 mikro-detik) pencacah melimpah
menjadi 0 (TF0=1)
53: TH0 = (-50000/256)-1;
54: TL0 = (-50000%256);
55:
56: TMOD = 0x11; //Timer 0 & 1 sebagai 16
bit counter
57: ET0 = 1; //Aktipkan interupsi
Timer 0
58: EA = 1; //Aktipkan Sistem
interupsi MCS51
59: TR0 = 1; //Jalankan Timer 0
60:
61: while(1) //4 baris berikut ini
diulang tanpa henti
62: {
63: P1 = Ruas[0]; //mengatur Ruas
puluhan jam
64: P3 = 0xF7; //menghidupkan angka
puluhan jam
65: TungguSebentar();
66: P1 = Ruas[1]; //mengatur Ruas
satuan jam
67: P3 = 0xFB; //menghidupkan angka
satuan jam
68: TungguSebentar();
69: P1 = Ruas[2]; //mengatur Ruas
puluhan menit
70: P3 = 0xFD; //menghidupkan angka
puluhan menit
71: TungguSebentar();
72: P1 = Ruas[3]; //mengatur Ruas
satuan menit
73: P3 = 0xFE; //menghidupkan angka
satuan menit
74: TungguSebentar();
75: }
76: }
77:// ****** Melakukan perubahan angka Jam ******
78:void GantiJam (void){
79: Jam += 1; //Jam sebagai
'count-up counter'
80: if (Jam==24) Jam=0; //Kembalikan ke 00
jika sampai jam 24
81: PerbaruiTampilan();
82: }
83:// ****** Melakukan perubahan angka Menit
******
84:void GantiMenit(void){
85: Menit += 1; //Menit sebagai
'count-up counter'
86: if (Menit==60) { //jika sudah sampai
menit 60 ...
87: Menit = 0; //kembalikan menjadi
menit 00
88: GantiJam(); } //saatnya merubah
angka Jam
89: PerbaruiTampilan();
90: }
91:// ****** Melakukan perubahan angka Detik
******
92:void GantiDetik(void){
93: Detik += 1; //Detik sebagai
'count-up counter'
94: if (Detik==60)
{ //jika Detik menjadi 60 ..
95: Detik = 0; //Kembalikan menjadi
detik 00
96: GantiMenit(); }
97: PerbaruiTampilan();
98: }
99:// ****** Melakukan pemeriksaan tombol ******
100:
void PeriksaTombol (void){
101:
if (!TombolJam) GantiJam();
//ditekan, rubah angka Jam
102:
else
103:
if (!TombolMenit)
GantiMenit(); //ditekan, rubah angka Menit
104:
}
105:
/************************************************************\
106:
Rutin Layanan Interupsi (ISR)
untuk Timer 0
107:
Terjadi sekali setiap 50 mili
detik (20 kali/detik)
108:
\************************************************************/
109:
void TimerInterrupt(void) interrupt
1 using 1 {
110:
//Perbaharui dulu nilai awal
Timer 0
111:
//th0:tl0 diisi dengan -50000,
112:
//sebagai pencacah count-up
50000 pulsa kemudian
113:
//(=50000 mikro-detik) pencacah
melimpah menjadi 0 (TF0=1)
114:
TH0 = (-50000/256)-1;
115:
TL0 = (-50000%256);
116:
117:
Pencacah20 -= 1;
//Pencacah20 sebagai 'count-down counter'
118:
if (!Pencacah20) { //jika
Pencacah20 menjadi 0 ...
119:
Pencacah20 = 20; //nilai
awal Pencacah20
120:
PeriksaTombol();
121:
GantiDetik(); }
122:
}
Dengan rangkaian seperti gambar 1 Anda
tinggal isikan file
jam.hex
ini ke dalam IC
AT89C51 maka akan tampil jam yang sudah jadi seperti tampilan di atas.