Alhamdulillah, akhirnya selesai
juga....
Artikel ini ditujukan untuk beberapa
Sobatku yang sudah bersedia memberikan respon positif dan sudah barang tentu
sebagai ucapan terima kasih karena bersedia melirik pada blogger sederhana ini.
Adalah merupakan sebuah kehormatan yang tak terkira nilainya dapat menerima
komentar maupun pesan melalui e-mail.
Mohon maaf juga karena beberapa
waktu ini sempat vakum dari kegiatan tulis-menulis artikel karena kesibukan
pekerjaan yang cukup menyita waktu.
Pencacah
naik (up counter) yang akan kita bahas merupakan pencacah dekade menggunakan format
BCD. Pada contoh aplikasi berikut, rangkaian dapat mencacah dalam 5 digit atau
0 sampai 99999. Namun bukan merupakan kendala jika ingin menambah jumlah digit
lebih dari 5. Sobat bisa dengan mudah menambahkan jumlah digit sebanyak
register yang ada. Bagaimana?
Menarik bukan. Hal ini bisa dilaksanakan karena secara prinsip kerja dalam
pencacahan, kita akan menggunakan register dari mikrokontroler untuk mencacah
dengan kombinasi perintah INC A (increment) dan DA A (decimal adjust) melalui
register akumulator.
Rangkaian yang akan kita buat dan
sudah penulis realisasikan pada sistem pencacah HASIL pada sebuah pabrik yang
tentunya karena alasan etika tidak disebutkan. Rangkaian memiliki masukan
sebanyak 4 saluran yang secara independen akan menaikkan cacahan. Masing-masing
masukan terhubung pada sakelar PUSH-ON di mana jika ditekan akan menaikkan
cacahan sejumlah masukan yang ditekan meskipun secara bersamaan. Jadi jika
salah satu ditekan maka cacahan akan bertambah satu dan jika ada 4 sakelar
ditekan bersamaan maka cacahan akan bertambah 4 karena setiap masukan bersifat
independen dan merupakan akumulasi dari tiap masukan yang ditekan.
Sebagai catatan jika menginginkan
jumlah masukan lebih dari 4, maka hal tersebut bukan merupakan masalah. Sama
halnya dengan jumlah digit maksimum yang diinginkan. Untuk jelasnya kita lihat
blok diagram kerja rangkaian kita.
Pada gambar diagram di atas
terdapat 4 saluran masukan yang masing-masing akan menghasilkan nilai +1 atau
cacahan naik (pada aplikasi program) jika dipicu. Hasil cacahan dari setiap
masukan akan diakumulasi untuk kemudian ditampilkan pada keluaran. Ternyata oh
ternyata, penulis memutuskan bentuk keluaran dari hasil cacahan dalam bentuk
format data serial.
Sebagai tambahan saja, maka hasil
cacahan akan disimpan dalam memori menggunakan AT93C46 sehingga tidak akan
hilang meskipun catu daya dipadamkan di mana proses pencacahan dapat
dilanjutkan dilain waktu. Dalam aplikasi yang penulis tujukan adalah dalam
proses kerja di pabrik di mana pada waktu istirahat makan maka perangkat bisa
di matikan sementara waktu istirahat untuk menghemat energi listrik.
Tentu Sobat ada yang bertanya, kenapa
keluarannya berbentuk serial?
Jawabnya sederhana saja.
Pada aplikasi yang sudah dibuat
dan direalisasikan, saat desain ini dibuat, terdapat 2 buah tampilan, yaitu
TARGET dan HASIL. Masing-masing memiliki jumlah digit yang sama. Sudah barang
tentu memiliki rangkaian yang sama. Dan untuk keluwesan dalam pengembangan
selanjutnya maka nantinya peraga juga dapat fleksibel apakah ingin menggunakan
peraga LED 7 segmen atau LCD atau bahkan menggunakan komputer atau diinginkan
dalam rangkaian jaringan di mana terdapat lebih dari satu pencacah dan
terhubung dengan PC. Sebagai bocoran saja, pengembangan dari rangkaian di atas
selanjutnya, ternyata dari pihak pengguna menginginkan tambahan tampilan WAKTU.
Nah, jadi tidak perlu membuat rangkaian baru kan. Cukup menambah peraga digit
dan sedikit modifikasi aplikasi programnya saja, selesai.
Sebelum bertele-tele dalam
pembahasannya, Yuk kita lihat rangkaian lengkap pencacah yang dimaksud.
Ada sedikit modifikasi pada
rangkaian atas dari desain aslinya. Pada desain aslinya penulis menggunakan IR
(infrared) sensor untuk penyetelan pada gerbang P32 dan menggantinya dengan
sakelar tekan untuk RESET.
Otak dari rangkaian pencacah
adalah mikrokontroler AT89C2051. Untuk masukannya dibuat dengan komparator
dengan LM339 yang terdiri dari 4 buah. Jika diinginkan bisa menjadi 8 masukan
dan tentu jumlah LM339 juga menjadi 2 buah. Seperti sudah dibahas di atas maka
untuk menyimpan data cacahan digunakan memori AT93C46. Memori digunakan untuk
informasi UNIT NUMBER yang berguna pada aplikasi jaringan dan tentu informasi
HASIL cacahan.
Penggunaan komparator di atas
dimaksudkan untuk mengurangi resiko riple pada sakelar. Adanya ambang
histerisis dan filter kapasitif memungkinkan resiko tersebut tereliminasi alias
aman. Apalagi jika masukan terkoneksi menggunakan kabel yang cukup jauh dari
lokasi perangkat.
Dalam implementasi, masukan tidak
harus berupa sakelar PUSH ON. Masukan bisa saja berupa sensor apa saja yang
penting sifatnya normally opened atau dalam keadaan idle harus terbuka. Penulis
sudah coba dengan MC (magnetic contact) dan Beam Sensor (active infra red). Mengasikkan juga saat mencoba-coba beragam jenis sensor
untuk masukan.
Dalam keadaan normal di mana
COMMON dari masukan adalah VCC maka tegangan masukan adalah -5 volt yang
terhubung pada masukan membalik (-). Masukan juga terhubung pada resistor PULL
DOWN (R1) bernilai 4k7 (nilai ini bisa Sobat ganti antara 2k2 sampai
47k sesuai selera menurut implementasinya). Tegangan referensi pada masukan tak
membalik (+) adalah hasil bagi dari R2, R3 dan R4
yang masing-masing bernilai 47k. Karena pada keadaan normal masukan (-) lebih
rendah dari masukan (+) maka keluaran komparator (open collector) adalah CUT
OFF. Perhitungan sederhananya akan menghasilkan tegangan referensi sebesar 2/3
dari VCC di mana VCC adalah 5 volt sehingga VREF adalah 3,333 volt.
Nilai ini muncul jika keluaran tidak terhubung pada gerbang mikrokontroler atau
terhubung pada port P10 dan atau P11. Jika terhubung pada
gerbang lainnya yang memiliki resistor Pull-up 50k maka nilai VREF
secara perhitungan sederhana menjadi mendekati ¾ dari VCC atau 3,75 volt. Hal
ini jangan dijadikan masalah yang berarti karena tidak terlalu mempengaruhi
hasil kerjanya, percaya saja deh.
Kemudian jika masukan terhubung
singkat pada COMMON maka tegangan masukan (-) akan lebih tinggi dari masukan
(+) yang menyebabkan keluaran komparator menjadi SATURASI. Ini akan mengubah
VREF menjadi 1/3 dari VCC yaitu 1,667 volt pada semua jenis port dari
mikrokontroler. Dari proses tersebut maka ada ambang histerisis sebesar 1,667
volt di mana bisa disimpulkan bahwa nilai besaran UTP (upper trip point) adalah
3,333 volt atau 3,75 volt dan LTP (lower trip point) adalah 1,667 volt.
Rasanya, pembahasan untuk kemudi
masukan menggunakan komparator sudah cukup jelas. Sekarang kita memasuki
pembahasan pada program aplikasi yang harus dijalankan oleh mikrokontroler
AT89C2051 atau AT89S2051. Penyerderhanaan program dapat dilihat berikut ini:
$mod51
Saklar1 bit p1.0
Saklar2 bit p1.1
Saklar3 bit p1.2
Saklar4 bit p1.3
IR_Sensor bit p3.2
DIO bit p3.3
RST bit p3.4
CLK bit p3.5
Gerbang P10 sampai P13
didefinisikan sebagai saluran masukan seperti baris di atas sebagai Saklar1-4.
Selanjutnya P32 juga didefinisikan sebagai masukan. Di atas P32
tertulis sesuai versi aslinya sebagai IR_Sensor tapi pada artikel ini dialih
fungsikan sebagai tombol RESET. Sementara P33 sampai P35 untuk antarmuka dengan
EEPROM AT93C46 untuk menyimpan data cacahan.
BuffHasil data 08h
RegBit0 data 28h
BitSaklar1 bit RegBit0.0
BitSaklar2 bit RegBit0.1
BitSaklar3 bit RegBit0.2
BitSaklar4 bit RegBit0.3
RegBit1 data 29h
BitAngka bit RegBit1.4
Fail bit RegBit1.7
Register RAM pada mikrokontroler yang
digunakan adalah BuffHasil pada 08H untuk mengolah dan menyimpan cacahan sebanyak
5 byte. Untuk proses pencacahan juga digunakan register bit yaitu 28H dan 29H.
RegStack equ 38h
ROM_Memori equ 0
Usai menetapkan lokasi Stack Pointer dan
alokasi memori pada EEPROM, maka kita bisa menuliskan program yang akan
dijalankan dimulai dengan inisialisasi untuk fitur komunikasi serial. Isi
register TH1 dan TL1 adalah E8H untuk buadrate 1200 bps. Inisialisasi
dilanjutkan ke alamat berinisial Inisialisasi agar tidak memangkas lokasi
interupsi serial pada 0023H.
org 0000h
mov sp,
#RegStack-1
mov p1,
#255
mov p3,
#255
mov RegBit,
#0
mov pcon,
#0
mov tmod,
#20h
mov scon,
#50h
mov ie,
#90h
mov tl1,
#0e8h
mov th1,
#0e8h
setb tr1
ajmp Inisialisasi
Sebenarnya lokasi 0023H di bawah ini tidak
dijalankan dan bisa ditiadakan jika diinginkan. Tapi dari pada ada kesalahan
maka penulis tetap masukkan.
org 0023h
reti
Program berikutnya adalah subrutin yang
dijalankan untuk mengirim data cacahan melalui gerbang serial. Kode pertama
yang dikirim adalah karakter “B” yang merupakan identitas peraga nantinya. Kode
tersebut boleh saja diganti dengan “A”. Penjelasannya akan dapat dilihat pada
bagian peraga nanti.
KirimHasil:
mov a,
#'B'
acall KirimSerial
mov r1,
#BuffHasil
Register R1 berisi alamat register cacahan
yang akan ditampilkan atau dikirim. Register R0 adalah jumlah 4 digit pertama
yang akan dikirim. Proses menggunakan register R0 dimaksudkan untuk
menghilangkan tampilan “0” diawal digit. Sehingga jika nilai cacahan sebagai
contoh adalah “123” dan bukan ditampilkan sebagai “00123” di mana nilai “0”
diawal akan digantikan dengan spasi. Sementara itu digit terakhir wajib
ditampilkan meski nilai cacahan 0.
KirimDisplay:
mov r0,
#4
clr BitAngka
AngkaSpasi:
mov a, @r1
jb BitAngka, DataAngka
jz DataSpasi
setb BitAngka
DataAngka:
orl a, #30h
ajmp KirimAngka
DataSpasi:
orl a, #20h
KirimAngka:
inc r1
acall KirimSerial
djnz r0, AngkaSpasi
mov a, @r1
orl a, #30h
acall KirimSerial
ret
Ini prosedur program mengirim informasi
data secara serial melalui gerbang P31.
KirimSerial:
clr ea
mov sbuf,
a
jnb ti, $
clr ti
setb ea
ret
Berikut adalah lanjutan dari program inisialisasi dengan memeriksa kondisi
masukan saklar pada saat awal unit dihidupkan. Proses dilanjutkan dengan
mengambil nilai cacahan yang tersimpan pada EEPROM.
Inisialisasi:
jnb Saklar1, $
jnb Saklar2, $
jnb Saklar3, $
jnb Saklar4,
$
acall AT93C46_RESET
mov dptr,
#ROM_Memori
mov r0,
#BuffHasil
mov r1,
#5
acall BacaData
mov r5,
#32
IniTund1:
mov r6, #255
IniTund2:
mov r7, #255
djnz r7, $
djnz r6, IniTund2
djnz r5, IniTund1
Sebelum data cacahan dikirim, diberikan
tundaan selama beberapa detik menggunakan register R5, R6 dan R7 seperti di
atas, untuk memberi kesempatan peraga juga menyelesaikan proses inisialisasi.
IniDisplay:
acall KirimHasil
Hasil cacahan pada kondisi “idle” akan
terus disegarkan selang beberapa saat dengan proses tunda seperti dialokasikan
dengan register di bawah ini, masih sama menggunakan R5, R6 dan R7.
AppMulai:
mov r5,
#64
Mulai1:
mov r6, #255
Mulai2:
mov r7, #255
Gerbang IR_Sensor adalah tombol RESET. Jika ditekan akan memberi masukan
berlogika rendah dan memaksa program menjalankan subrutin ResetHasil. Jika
tidak ditekan atau logika tinggi maka proses pemeriksaan saklar akan dijalankan
pada AppSaklar1.
AppSensor:
jb IR_Sensor, AppSaklar1
acall ResetHasil
ajmp AppMulai
AppSaklar1:
jb Saklar1,
AkhirSaklar1
jb BitSaklar1,
AppSaklar2
setb BitSaklar1
acall TambahHasil
ajmp AppSaklar2
AkhirSaklar1:
clr BitSaklar1
Proses pada AppSaklar1 sampai 4 adalah
mirip. Jika diinginkan ini bisa ditambah sampai dengan 8 dengan mengubah
konfigurasi awal dan rangkaiannya tentu. Jika gerbang Saklar(n) rendah maka
BitSaklar(n) akan diperiksa jika tinggi maka diabaikan untuk proses pencacahan
naiknya, tapi jika rendah maka akan diset tinggi untuk kemudian menjalankan
subrutin TambahHasil. Kondisi gerbang Saklar(n) tinggi akan mereset
BitSaklar(n) pada AkhirSaklar(n).
AppSaklar2:
jb Saklar2, AkhirSaklar2
jb BitSaklar2, AppSaklar3
setb BitSaklar2
acall TambahHasil
ajmp AppSaklar3
AkhirSaklar2:
clr BitSaklar2
AppSaklar3:
jb Saklar3, AkhirSaklar3
jb BitSaklar3, AppSaklar4
setb BitSaklar3
acall TambahHasil
ajmp AppSaklar4
AkhirSaklar3:
clr BitSaklar3
AppSaklar4:
jb Saklar4, AkhirSaklar4
jb BitSaklar4, AppSaklar1
setb BitSaklar4
acall TambahHasil
ajmp MulaiKembali
AkhirSaklar4:
clr BitSaklar4
Proses pemeriksaan status saklar sampai di
sini, selanjutnya adalah menjalankan rutin tunda untuk pengiriman data serial
secara periodik.
MulaiKembali:
djnz r7, AppSensor
djnz r6, Mulai2
djnz r5, Mulai1
ajmp IniDisplay
Nah, subrutin mencacah naik dijalankan pada
TambahHasil. Biar aman nilai bit CY (carry flag) dan AC (auxilliary carry)
direset ke rendah.
TambahHasil:
clr cy
clr ac
Pencacahan naik dari register diawali dari
LSB atau digit terakhir yaitu BuffHasil+4 atau lokasi 0CH. Meskipun perintah
INC bisa dijalankan pada register 0CH tapi sebaiknya menggunakan register
akumulator karena akan dilanjutkan dengan perintah DA untuk mengubahnya dalam
format BCD. Jadi jika nilai akumulator adalah 0AH maka akan berubah menjadi
10H. Jika seperti ini maka register B diperlukan untuk menyimpan nible MSB
untuk proses pada register cacahan selanjutnya. Sebelum hasil cacahan pada
akumulator dikembalikan ke register BuffHasil maka nilai pada nible MSB
dibersihkan terlebih dahulu. Nible MSB juga perlu dipindahkan dengan perintah
SWAP menjadi nible LSB.
mov a,
BuffHasil+4
inc a
da a
mov b, a
anl a, #0fh
mov BuffHasil+4,
a
xch a,
b
swap a
anl a,
#0fh
xch a,
b
Nah, proses pencacahan pada register
BuffHasil(n) selesai. Untuk register selanjutnya yaitu BuffHasil(n-1) adalah
serupa dengan di atas.
mov a,
BuffHasil+3
add a, b
da a
mov b, a
anl a, #0fh
mov BuffHasil+3,
a
xch a,
b
swap a
anl a,
#0fh
xch a,
b
mov a,
BuffHasil+2
add a, b
da a
mov b, a
anl a, #0fh
mov BuffHasil+2,
a
xch a,
b
swap a
anl a,
#0fh
xch a,
b
mov a,
BuffHasil+1
add a, b
da a
mov b, a
anl a, #0fh
mov BuffHasil+1,
a
xch a,
b
swap a
anl a,
#0fh
xch a,
b
mov a,
BuffHasil
add a, b
da a
mov b, a
anl a, #0fh
mov BuffHasil,
a
xch a,
b
swap a
anl a,
#0fh
Proses mencacah naik dari kelima register
sudah selesai. Jika register melampaui nilai 99999 maka hasilnya adalah reset
menjadi 00000. Setelah proses mencacah maka akan dilanjutkan dengan menyimpan
hasil cacahan.
jnz ResetHasil
mov dph,
#0
ajmp SimpanHasil
Catatan:
Untuk jumlah digit lebih besar maka
BuffHasil bisa diperluas. Jika diinginkan untuk pencacahan sampai 10 digit maka
dibutuhkan 10 register dan proses di atas harus diawali pada BuffHasil+9. Dari
konfigurasi di atas maka Sobat bisa mencacah hingga 32 digit di mana bisa
dimulai dengan BuffHasil+31 dan seterusnya sehingga nilai maksimum cacahan
adalah 99.999.999.999.999.999.999.999.999.999.999. Mungkin saja cacahan sebesar
itu diperlukan, tergantung implementasi Sobat saja.
Berikut adalah subrutin untuk me-RESET
nilai cacahan yaitu mengisi nilai seluruh register dengan 00H. Dan setiap
perubahan dari isi register cacahan akan disimpan dalam EEPROM.
ResetHasil:
mov r0,
#BuffHasil
mov r1,
#5
PeriksaBuffHasil:
mov a, @r0
jnz ResetBuffHasil
inc r0
djnz r1, PeriksaBuffHasil
ret
ResetBuffHasil:
mov BuffHasil, #0
mov BuffHasil+1, #0
mov BuffHasil+2, #0
mov BuffHasil+3, #0
mov BuffHasil+4, #0
SimpanHasil:
mov dptr, #ROM_Memori
mov r0, #BuffHasil
mov r1, #5
acall SimpanData
acall KirimHasil
ret
Subrutin selanjutnya adalah berkenaan
dengan proses baca-tulis pada EEPROM AT93C46.
SimpanData:
acall AT93C46_EWEN
SimpData:
mov a, @r0
acall AT93C46_WRITE
inc r0
inc dptr
djnz r1,
SimpData
ret
BacaData:
acall AT93C46_READ
mov @r0,
a
inc r0
inc dptr
djnz r1,
BacaData
ret
AT93C46_RESET:
clr CLK
setb RST
clr RST
ret
WriteSerialBit:
push acc
push 07H
mov r7,
#8
NxtWRBit:
rlc a
jc WRBitH
clr DIO
ajmp WRClk
WRBitH:
setb DIO
WRClk:
clr CLK
setb CLK
djnz r7,NxtWRBit
pop 07H
pop acc
ret
ReadSerialBit:
push 07H
clr a
mov r7,
#8
setb DIO
RDClk:
clr CLK
setb CLK
jb DIO,
RDBitH
clr c
ajmp ShiftInBit
RDBitH:
setb c
ShiftInBit:
rlc a
djnz r7,
RDClk
pop 07H
ret
CheckEEPROM:
push 07H
push 06H
push 05H
mov r5,
#2
mov r7,
#255
mov r6,
#255
clr Fail
setb DIO
clr RST
setb RST
WaitBusy:
clr CLK
setb CLK
jb DIO,
WaitTimer1
mov r5,
#2
ajmp WaitReady
WaitTimer1:
djnz r7, WaitBusy
mov r7, #255
djnz r5, WaitBusy
setb Fail
ajmp Ready
WaitReady:
clr CLK
setb CLK
jnb DIO,
WaitTimer2
ajmp Ready
WaitTimer2:
djnz r6, WaitReady
mov r6, #255
djnz r5, WaitReady
setb Fail
Ready:
pop 05H
pop 06H
pop 07H
ret
AT93C46_WRITE:
push acc
setb RST
mov a,
#00000010b
acall WriteSerialBit
mov a,
dpl
orl a,
#10000000b
acall WriteSerialBit
pop acc
acall WriteSerialBit
acall CheckEEPROM
clr RST
ret
AT93C46_READ:
push 07H
push 06H
mov r6,
#2
mov r7,
#255
clr Fail
setb RST
mov a,
#00000011b
acall WriteSerialBit
mov a,
dpl
anl a,
#01111111b
acall WriteSerialBit
setb DIO
Dummy:
jb DIO,
WaitTimer3
ajmp DataReady
WaitTimer3:
djnz r7, Dummy
mov r7, #255
djnz r6, Dummy
setb Fail
ajmp EndReadEEPROM
DataReady:
acall ReadSerialBit
EndReadEEPROM:
clr RST
pop 06H
pop 07H
ret
AT93C46_EWEN:
push acc
setb RST
mov a, #00000010b
acall WriteSerialBit
mov a,
#01100000b
acall WriteSerialBit
clr RST
pop acc
ret
AT93C46_EWDS:
push acc
setb RST
mov a,
#00000010B
acall WriteSerialBit
mov a,
#00000000B
acall WriteSerialBit
clr RST
pop acc
ret
end
Sudah ya, terima kasih
sudah membaca artikel aku. Semoga
bermanfaat dan bisa diterapkan oleh sobat semua.
Salam....