Laporan Modul 2, EL3006 Timer/Counter dan Interrupt Jongguran Sondang DN (132 05 110)/ Kelompok 48/ Jumat, 14 Maret 2008 Asisten: Virgilius
Abstrak – pada praktikum kali ini, praktikan diharapkan mampu membuat program menggunakan timer pada mikrokontroler 8051 dalam berbagai variasi mode timer dan jenis timer seta mampu membuat program dengan memanfaatkan fasilitas interupsi yang tersedia pada mikrokontroler. Pada praktikum kali ini kami menggunakan DT-51 MinSys yang merupakan sebuah sistem minimum berbasis mikrokontroler 89C51 dan DT-51 Trainer Board yang merupakan board pendukung yang digunakan untuk memberikan masukan dan melihat respon keluaran dari program yang kita download ke dalam DT-51 MinSys.
I.
Data Percobaan
A. 1. 2. 3. 4. 5. 6. 7.
Alat dan Komponen yang Digunakan DT-51 MinSys DT-51 Trainer Board Komputer Power supply Kabel serial DB-9 pin Kabel tipe-x dan tipe-y Kabel untuk power DT-51 MinSys
B.
Isi Data Percobaan
1
2
3
Pemrograman mikrokontroler ini menggunakan bahasa assembly. Pada percobaan, digunakan beragam instruksi lompatan, logika, dan aritmatika, di antaranya Tabel 1 Set instruksi Assembly yang digunakan Mnemonik MOV MOVX SJMP LJMP SETB CLR JB JNB JC JNC CJNE ACALL RET DJNZ RETI PUSH POP RL RR INC DEC
Fungsi Operasi Pemindahan data antar lokasi dalam RAM internal atau lokasi-lokasi SFR tanpa melalui akumulator Membaca RAM eksternal Mengodekan alamat tujuan sebagai sebuah offset relatif Mengodekan alamat tujuan sebagai konstanta 16-bit, panjang instruksinya 3 bit Mengeset nilai bit dengan nilai 1 Mengeset nilai bit dengan nilai 0 Meloncat jika nilai bitnya sama dengan 1 Meloncat jika nilai bitnya tidak sama dengan 1 Meloncat jika ada nilai bit carry di PSW Meloncat jika tidak ada nilai bit carry di PSW Meloncat jika dua nilai yang dibandingkan tidak sama Memanggil program sub rutin dalam daerah memoriprogram 2 kb yang setara Mengakhiri program sub rutin Mengurangi isi di register dan loncat jika tidak sama dengan 0 Mengakhiri sub rutin program layanan interupsi Menambah stack pointer Mengurangi stack pointer Memutar register ke kiri 1 bit Memutar register ke kanan 1 bit Menaikkan suatu nilai (1 byte) pada register Menurunkan suatu nilai (1 byte) pada register
Langkah-langkah yang kami lakukan dalam percobaan ini adalah mengetikkan listing program dalam ekstensi *.asm, meng-assemble listing program ke dalam bentuk *.hex, dan men-download-nya ke dalam DT-51 MinSys menggunakan kabel serial. Percobaan-percobaan yang kami lakukan antara lain
8
7
4 5
1.
Percobaan I : Timer/Counter 0 sebagai Timer Mode 0/1
2.
Percobaan II : Timer/Counter 0 sebagai Counter Mode 2 (8-bit AutoReload)
3.
Percobaan III : Penggunaan INT0 dengan Interrupt Enable
4.
Percobaan IV : Penggunaan INT0 dan INT1 dengan Interrupt Priority
6 Gambar 1 DT-51 MinSys Keterangan gambar DT-51 MinSys 1. Mikrokontroler AT89C51 2. EEPROM 3. Programmable Peripheral Interface (PPI) 4. Memori eksternal sebesar 8 MB 5. Port 1, Port A, Port B, dan Port C 6. Port Control 7. Kristal sebagai clock generator yang memiliki frekuensi 11,0592 MHz. Maka periode osilatornya adalah 0,090422453 µs 8. Port kabel serial PC
II. Analisis Hasil Percobaan 1.
Percobaan I : Timer/Counter 0 sebagai Timer Mode 0/1
$MOD51 ORG 4000H LJMP ORG
4100H
START
START:
MOV MOV MOV MOV CLR MOV MOV MOV SETB MOV
R0,#00H R1,#00H SP,#30H P1,#0FFH P1.4 TMOD,#01H TH0,0D8H TL0,#0EFH TR0 A,#0FFH
CHECK:
JNB LCALL LJMP
TF0,CHECK RELOAD PENGALI1
PENGALI1:
INC CJNE MOV LJMP
R0 R0,#32H,CHECK R0,#00H LED
LED:
CJNE LJMP
A,#00H,NYALA MATI
MATI:
CLR MOV LJMP
P1.4 A,#0FFH CHECK
NYALA:
SETB MOV LJMP
P1.4 A,#00H CHECK
RELOAD:
CLR MOV MOV CLR SETB RET END
TR0 TH0,#0D8H TL0,#0EFH TF0 TR0
$mod51 adalah file header perintah yang digunakan pada DT-51 MinSys. CSEG merupakan perintah untuk menentukan program memory space. Instruksi LJMP memerintahkan lompat ke sub program START. Kita memindahkan stack pointer ke alamat 30h. Stack pointer dipindahkan ke alamat 30h karena alamat-alamat sebenarnya masih dipakai. Stack pointer berada pada alamat 81h. Pada sub program start kita melakukan proses pemindahan data immediate ke register R0 dan R1. Kemudian kita juga melakukan pemindahan data immediate #0FFh ke port satu. Perintah ini akan membuat seluruh bit pada port satu mendapat harga logika satu. Pada baris selanjutnya terdapat perintah CLR yang berfungsi membuat logika port 1.4 menjadi nol. Pada baris selanjutnya terdapat perintah MOV yang akan memasukkan harga data immediate ke dalam register TMOD. Harga yang dimasukkan ini akan berfungsi menentukan mode timer yang digunakan. Jika kita memasukkan nilai #01h sebagaimana dalam program, maka kita akan membuat mode timer yang berfungsi menjadi mode 01. Hal ini dapat dilihat dalam penjelasan mode TMOD dan tabelnya seperti berikut
Langkah selanjutnya kami memindahkan nilai direct byte ke register TH0 dan memindahkan immediate data ke register TL0. Kemudian dengan perintah SETB kami mengaktifkan bit TR0. Setelah itu kami memindahkan nilai immediate FF ke accumulator A. Setelah itu program akan memasuki subrutin CHECK. Pada subrutin CHECK didapatkan instruksi JNB. Instruksi ini menyatakan bahwa program akan melompat ke subrutin CHECK jika harga TF0 sama dengan nol. Jika harga TF0 adalah satu, maka program akan melanjutkan ke instruksi LCALL. Instruksi LCALL (Long Subroutine Call) ini akan memanggil subrutin RELOAD. Setelah memanggil subrutin RELOAD, maka program akan langsung melompat ke subrutin PENGALI1. Pada subrutin RELOAD, pertama-tama nilai register TR0 akan diset menjadi nol. Kemudian instruksi MOV akan memindahkan nilai immediate DBh ke register TH0 dan nilai immediate EFh ke register TL0. Setelah melakukan ini, maka program pun akan mengeset nilai TF0 ke nilai nol dan TR0 ke nilai satu. Setelah ini program akan kembali ke instruksi LJMP untuk langsung memasuki subrutin PENGALI1. Pada subrutin PENGALI1, program dilanjutkan dengan instruksi INC yang menaikkan (increment) register R0. Setelah itu program dilanjutkan dengan instruksi CJNE yang menyatakan bahwa program akan melompat ke subrutin CHECK kembali apabila nilai R0 tidak sama dengan 32h. Selama nilai register ini belum mencapai 32h, maka program akan terus berputar di sini. Setelah nilai register sama dengan 32h, maka program akan dilanjutkan dengan mengeset nilai register R0 ke nilai nol kembali dan setelah itu program pun akan melompat ke subrutin LED. Pada subrutin LED terdapat instruksi CJNE yang menginstruksikan program untuk membandingkan harga kedua data, yaitu harga accumulator dan data immediate 00h. Jika keduanya memiliki harga yang berbeda, maka program akan melompat ke subrutin NYALA. Jika harga pada accumulator adalah nol, maka program akan langsung melompat ke subrutin MATI. Karena pada awalnya nilai accumulator telah diset menjadi satu, maka program pun akan melompat ke subrutin NYALA. Pada subrutin NYALA, harga port output yang telah dihubungkan dengan port satu bit keempat diberi instruksi SETB. Dengan instruksi ini, maka port output pun akan menyala. Setelah instruksi SETB yang mengeset port output bit keempat, maka program dilanjutkan dengan instruksi MOV yang memindahkan data immediate 00h ke accumulator A.
Setelah itu program akan memanggil subrutin CHECK (kembali ke CHECK). Kembali ke subrutin CHECK, maka program akan melalui alur yang sama dengan sebelumnya. Tetapi program pun akan sampai ke subrutin MATI karena pada saat program ada di subrutin NYALA, nilai accumulator A telah diset ke nilai nol. Pada subrutin MATI, port output bit keempat pun diset ke nilai nol. Sehingga pada saat ini LED pun akan padam. Setelah itu nilai accumulator pun akan diset menjadi nilai satu. Setelah ini program pun akan melanjutkan ke subrutin CHECK dan begitu seterusnya. Untuk program modifikasinya, kami membuat antara empat bit LSB dengan empat bit MSB berkedip secara bergantian dengan waktu periode kedip LED berkisar pada x detik. Dimana x didefinisikan sebagai berikut X = (modulus 9 dari no grup) + 1 Karena nomor grup kami adalah 48. Maka modulus-9 nya adalah tiga. Sehingga x adalah 4 detik. Jika pada program sebelumnya, port output yang berkedip hanyalah bit empat saja, maka kini port output yang aktif adalah 8 buah. Untuk itu maka kami melakukan inisialisasi harga port output dahulu pada subrutin START. Karena keempat bit output menyala bergantian, maka nilai awal yang harus dimasukkan haruslah berkelompok empat empat dengan nilai yang berbeda. Kemudian karena pada program sebelumnya delay yang dihasilkan adalah satu detik, maka untuk program kali ini kami hanya perlu membuat delay tersebut dikali dengan empat. Hal ini membuat batas nilai R0 yang di-increment diubah menjadi 4 kali 32h, yaitu B2h. Sehingga program modifikasinya adalah $MOD51 ORG 4000H LJMP MOV MOV MOV MOV SETB SETB SETB SETB CLR CLR CLR CLR MOV MOV MOV SETB MOV
START R0,#00H R1,#00H SP,#30H P1,#0FFH P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7 TMOD,#01H TH0,0D8H TL0,#0EFH TR0 A,#0FFH
CHECK:
JNB LCALL LJMP
TF0,CHECK RELOAD PENGALI1
PENGALI1:
INC CJNE MOV LJMP
R0 R0,#0B2H,CHECK R0,#00H LED
LED:
CJNE LJMP
A,#00H,NYALA MATI
START:
MATI:
SETB SETB SETB SETB CLR CLR CLR CLR MOV LJMP
P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7 A,#0FFH CHECK
NYALA:
CLR CLR CLR CLR SETB SETB SETB SETB MOV LJMP
P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7 A,#00H CHECK
RELOAD:
CLR MOV MOV CLR SETB RET END
TR0 TH0,#0D8H TL0,#0EFH TF0 TR0
2.
Percobaan II : Timer/Counter 0 sebagai Counter Mode 2 (8-bit AutoReload) $MOD51 CSEG ORG LJMP
4000H START
START:
MOV MOV MOV MOV CLR MOV SETB
P1,#00H TMOD,#06H TH0,#0FBH TL0,#0FBH TF0 A,#00H TR0
LED1:
MOV SUBB JB MOV LJMP
A,TL0 A,#0FBH TF0,LED2 P1,A LED1
LED2:
MOV ACALL LJMP
P1,#0FFH DELAY START
DELAY: LUP1: LUP2:
MOV MOV MOV DJNZ DJNZ DJNZ RET END
R7,#04H R6,#0FFH R5,#0FFH R5,$ R6,LUP2 R7,LUP1
Pada percobaan ini kami menggunakan port 1 sebagai output. Kami juga memasang kabel penghubung antara IS3 dengan T0.
dengan nol. Di bawahnya terdapat instruksi yang sama untuk register R6 dan R7. Selama register R6 tidak nol, maka register tersebut akan dikurangi dan program akan melompat ke subrutin LUP2. Hal yang sama dilakukan untuk register R7. Program akan melompat ke subrutin LUP1 selama nilainya tidak sama dengan nol. Kami juga memodifikasi listing program tersebut sehingga momen LED menyala semua sejenak setelha tombol ditekan sejumlah x kali dengan x didefinisikan dengan X = (modulus 9 dari no grup) + 1 Untuk itu kami membuat program sebagai berikut $MOD51
Yang dikerjakan dengan listing program di atas pertama-tama adalah memindahkan memori aktif ke alamat 4000H yang merupakan alamat pada EEPROM. Hal ini dilakukan dengan menuliskan perintah CSEG. Tujuannya adalah untuk menjaga apabila terjadi hal yang tidak diinginkan maka perintah masih tersimpan pada EEPROM dan tidak hilang. Kemudian program akan melanjutkan ke subrutin START dengan perintah LJMP. Di subrutin START pertama-tama kita akan memindahkan nilai immediate 00h ke port P1. Sehingga pada saat ini port 1 yang terhubung ke output akan bernilai nol untuk semua bit. Selanjutnya kita melanjutkan ke instruksi MOV yang memindahkan nilai immediate 06h ke register TMOD. Hal ini dilakukan untuk mengeset mode timer yang akan digunakan. Dengan memasukkan nilai heksadesimal sebesar 06h, maka yang diset adalah bit C/~T(0) dan bit M1(0). Hal ini berarti bahwa fungsi yang dijalankan adalah counter, yaitu timer yang bersangkutan akan diincrement setiap transisi dari 1 ke 0 pada pin TX. Instruksi selanjutnya menyatakan pemidahan data immediate FBh ke TH0 dan TL0. Setelah itu program akan mengeset nilai TF0 menjadi nol dengan instruksi CLEAR dilanjutkan pemindahan data immediate 00h ke accumulator A. Kemudian TR0 pun akan diset ke nilai satu. Kemudian program akan melanjutkan ke subrutin LED1. Pada subrutin LED1 ini kita memindahkan harga TL0 ke accumulator A. Kemudian kami mengurangi immediate data FBh dari accumulator. Setelah itu instruksi JB akan membuat program melompat ke subrutin LED2 apabila TF0 memiliki nilai satu. Kemudian nilai accumulator dipindahkan ke port satu. Instruksi terakhir dalam subrutin ini adalah LJMP LED1 yang mengindikasikan bahwa program akan melompat kembali ke subrutin LED1. Pada subrutin LED2, nilai immediate FFh akan dipindahkan ke port satu. Kemudian program pun akan memanggil subrutin DELAY. Setelah kembali, maka program akan melompat kembali ke subrutin START. Sementara di subrutin DELAY, pertama-tama nilai immediate 04h akan dipindahkan ke register R7. Program akan melanjutkan ke subrutin LUP1 dengan instruksi yang memindahkan nilai FFh ke register R6 dan pada subrutin LUP2 yang memindahkan nilai FFh ke register R5. Setelah itu program akan melanjutkan ke instruksi DJNZ yang akan mengurangi register R5 dan akan jump ke awal selama nilai register tidak sama
CSEG ORG LJMP
4000H START
START:
MOV MOV MOV MOV CLR MOV SETB
P1,#00H TMOD,#06H TH0,#0FBH TL0,#0FBH TF0 A,#00H TR0
LED1:
MOV SUBB JB MOV LJMP
A,TL0 A,#0FBH TF0,LED2 P1,A LED1
LED2:
MOV ACALL LJMP
P1,#0FFH DELAY START
DELAY: LUP1: LUP2:
MOV MOV MOV DJNZ DJNZ DJNZ RET END
R7,#0FFH R6,#0FFH R5,#0FFH R5,$ R6,LUP2 R7,LUP1
Pada program modifikasi di atas, kami mengganti nilai pada port A di subrutin DISPLAY dengan 1816 yang merupakan representasi heksadesimal dari 4810. Kami juga mengganti switch input yang harus aktif pada bagian instruksi JB dengan switch input bit ke nol. 3.
Percobaan III : Penggunaan INT0 dengan Interrupt Enable $MOD51 CSEG ORG LJMP ORG RL MOV MOV LUPA: LUPB:
START:
4000H START 4003H A P1,A R7,#04H
MOV MOV DJNZ DJNZ DJNZ RETI
R6,#FFH R5,#0FFH R5,$ R6,LUPB R7,LUPA
ORG
4200H
MOV MOV MOV
SP,#30H TCON,#01H A,#01H
MOV MOV SJMP END
P1,#01H IE,#81H START
Pada percobaan kali ini kami menggunakan port 1 pada DT-51 MinSys sebagai port output dan menghubungkan IS1 dengan INT0. Program kali dimulai dengan memindahkan memori aktif ke alamat 4000H yang merupakan alamat pada EEPROM. Hal ini dilakukan dengan menuliskan perintah CSEG. Kemudian program akan melompat ke subrutin START. Kemudian program melanjutkan merotasi accumulator ke kiri. Setelah itu program akan memindahkan accumulator ke port satu dan memindahkan data immediate 04h ke register R7. Pada subrutin START nilai 30h akan dipindahkan ke stack pointer dan nilai 01h akan dipakai untuk menentukan TCON. Pada keadaan ini bit pada register TCON yang aktif adalah bit IT(x). Jika bit ini diaktifkan maka interupsi eksternal akan terjadi saat terjadi transisi dari nilai 1 ke nilai 0. Mode ini disebut juga dengan falling edge trigger.
Setelah menentukan mode pada register TCON, sekarang program beralih memindahkan nilai 01h ke accumulator dan ke port satu. Instruksi MOV di bawahnya pun menyatakan pemindahan data immediate 81h ke register IE. Hal ini akan menentukan bit mana dalam register yang akan aktif. Jika nilai 81h dimasukkan, maka interrupt pun akan aktif.
Kemudian untuk program modifikasi, kami diminta untuk membuat LED bit 0, bit 1, bit 6, dan bit 7 agar menyala. Ketika terjadi interrupt, maka bit ke 2, bit 3, bit 4, dan bit 5 yang akan menyala. Dan setelah interrupt selesai, maka LED pun akan kembali ke kondisi awal. Listing program yang baru adalah sebagai berikut
MOV MOV SJMP END
4.
Percobaan IV : Penggunaan INT0 dan INT1 dengan Interrupt Priority $MOD51 CSEG ORG LJMP
4000H START
ORG LJMP
4003H INTER0
ORG LJMP
4013H INTER1
ORG
4100H
INTER0:
MOV SETB LCALL CLR RETI
P1,#0H P1.0 LDELAY P1.0
INTER1:
MOV SETB LCALL MOV RETI
P1,#0H P1.7 LDELAY P1.7
ORG
4200H
LDELAY:
PUSH PUSH PUSH MOV
7 6 5 R7,#24H
LUPA:
MOV
R6,#0FFH
LUPB:
MOV DJNZ DJNZ DJNZ POP POP POP RET
R5,#0FFH R5,$ R6,LUPB R7,LUPA 5 6 7
SDELAY:
PUSH PUSH PUSH
7 6 5
MOV MOV MOV DJNZ DJNZ DJNZ POP POP POP RET
R7,#24H R6,#0FFH R5,#0FFH R5,$ R6,LUP2 R7,LUP1 5 6 7
START:
MOV MOV MOV MOV
SP,#30H TCON,#05H IP,#04H IE,#85H
LOOP1:
MOV ACALL MOV ACALL SJMP
P1,#01010101B SDELAY P1,#10101010B SDELAY LOOP1
LUP1: LUP2:
$MOD51 CSEG ORG LJMP ORG MOV MOV MOV LUPA: LUPB:
START:
4000H START 4033H A,#3CH P1,A R7,#04H
MOV MOV DJNZ DJNZ DJNZ RETI
R6,#5FH R5,#FFH R5,$ R6,LUPB R7,LUPA
ORG
4200H
MOV MOV MOV
SP,#30H TCON,#01H A,#0C3H
P1,#0C3H IE,#81H START
END
LOOP1:
Percobaan ini menggabungkan dua buah percobaan sebelumnya sehingga port PPI digunakan sebagai input dan output. Diatur pula alamat kedua port yang digunakan (Port A dan Port B). Program kali inipun menggunakan delay dengan cara membuat loop-loop pada sub rutin DELAY1, LUP2, dan LUP1. Lamanya delay dapat dihitung dengan cara menghitung jumlah siklus lalu dikalikan dengan lamanya satu siklus mesin, yaitu 12 periode osilator. Karena frekuensi kristal 11,0595 MHz maka satu siklus mesin 12 x 1/f = 0,09042 µs.
4000H START
ORG LJMP
4003H INTER0
ORG LJMP
4013H INTER1
ORG
4100H
INTER0:
MOV MOV LCALL MOV RETI
P1,#0H P1,#99H LDELAY P1,#66H
INTER1:
MOV MOV LCALL MOV RETI
P1,#0H P1,#0AAH LDELAY P1,#55H
ORG
4200H
LDELAY:
PUSH PUSH PUSH MOV
7 6 5 R7,#24H
LUPA:
MOV
R6,#0FFH
LUPB:
MOV DJNZ DJNZ DJNZ POP POP POP RET
R5,#0FFH R5,$ R6,LUPB R7,LUPA 5 6 7
SDELAY:
PUSH PUSH PUSH
7 6 5
III. Kesimpulan 1. 2.
MOV MOV MOV DJNZ DJNZ DJNZ POP POP POP RET
R7,#24H R6,#0FFH R5,#0FFH R5,$ R6,LUP2 R7,LUP1 5 6 7
MOV MOV MOV MOV
SP,#30H TCON,#05H IP,#01H IE,#85H
3.
4.
5.
LUP1: LUP2:
START:
P1,#11111111B SDELAY P1,#00000000B SDELAY LOOP1
END
$MOD51 CSEG ORG LJMP
MOV ACALL MOV ACALL SJMP
DT-51 MinSys dapat digunakan untuk membuat program yang memanfaatkan kontrol timer dan counter. Register yang dapat digunakan untuk menentukan mode timer dan kontrol timer antara lain TMOD, TCON, TH, dan TL. Register TMOD dan TCON merupakan register 8 bit. Register TMOD tidak dapat diakses per bit, sedangkan TCON dapat diakses per bit. Timer/Counter memiliki berbagai mode yang dapat digunakan sesuai kebutuhan, di antaranya mode 0, 1, dan 2. Register-register yang dapat digunakan untuk kontrol counter antara lain IE dan IP.
Daftar Pustaka [1] Modul Percobaan 1 Praktikum Sistem Mikrokontroler dan Lab [2] Putra, Agfianto Eko. 2003. Belajar Mikrokontroler AT89C51/52/55 (Teori dan Aplikasi). Yogyakarta : Penerbit Gaya Media.