Translate

Membuat Pintu Akses Sederhana Untuk Rumah Atau Kantor Kecil Dengan AT89C2051 Dan AT93C46


  
Perangkat pintu akses (access door controller) adalah perangkat yang digunakan pada sistem kunci pintu. Saat ini, perangkat itu banyak dipasarkan dari yang mahal dan canggih sampai yang murah meriah. Aku pernah memasang beberapa jenis dari yang mahal sampai yang murah. Bahkan harga di pasaran untuk perangkat yang paling murah hanya berharga berkisar 300 ribuan saja. Memang harga itu baru panelnya saja dan belum perangkat pendukung lainnya seperti power supply, electric door, tombol keluar dan kartu RFID serta instalasi kabel.

Karena postingan ini berjudul pintu akses sederhana, maka sebagai perbandingannya adalah perangkat akses berharga murah yang ada di pasaran. Tapi jangan kuatir, setelah diinstalasi maka penampilan alat kita tidak akan kalah keren dengan bahkan yang mahal sekalipun.

Sebagai perbandingan adalah panel akses berharga murah. Panel yang di pasarkan tersebut sudah lengkap di dalamnya termasuk pembaca kartu RFID. Panel yang ada di pasaran itu, umumnya bekerja secara mandiri (stand-alone) maksudnya sistem perangkat tidak memiliki fitur komunikasi yang dapat dihubungkan dengan PC untuk membentuk jaringan seperti layaknya perangkat yang mahal dan canggih.

Nah, di sini aku mau membuat panel akses dengan harga lebih murah dari pada panel termurah yang ada di pasaran tapi memiliki kelebihan bisa berkomunikasi dengan perangkat PC. Untuk identifikasinya aku pergunakan pembaca kartu RFID yang ada di pasaran dan berharga murah meriah. Sebagai perkiraan perbandingan harga, jika sobat mau coba maka modal yang dibutuhkan bisa menghemat sampai paling tidak 200 ribuan. Lumayan kan.

Konsepnya sederhana saja. Panel yang akan dibuat berbasis mikrokontroler dari Atmel yaitu AT89C2051. Kemudian untuk menyimpan data kartu menggunakan AT93C46/56/66 yang berkapasitas 128/256/512 byte, sedikit memang, tapi kebutuhan kita memang hanya untuk diimplementasikan pada perumahan dan kantor kecil dengan jumlah pengguna (user) tak lebih dari maksimal 42/85/170 kartu. Tapi jangan kuatir jika menginginkan jumlah yang banyak sobat bisa mengganti dengan memori yang lebih besar lagi seperti AT24C512 yang bisa diisi sampai 10 ribuan kartu ditambah record transaksinya. Tapi panel jadi enggak sederhana lagi terutama dalam programnya. Apalagi kalau ditambah menggunakan RTC (real time clock) untuk menunjukkan waktu dan fitur time zone atau apalah seperti panel akses yang canggih.

Tapi sobat enggak usah kuatir, aku pernah buat yang menggunakan AT24C512 dan nanti aku akan sampaikan deh. Sekarang kita bahas yang sederhana dulu ya....

Aku coba membuat panel ini dan sobat percaya nggak kalau harga komponennya nggak lebih dari 50 ribu? Tentu diluar harga pembaca kartunya (card reader) dimana aku menggunakan RFID 125kHz yang murah meriah. Rangkaian lengkapnya seperti berikut:



Dari rangkaian di atas bisa sobat perhatikan dengan seksama. Untuk masukan dan keluaran aku klasifikasikan sesuai jenisnya dan menggunakan konektor yang terpisah. Dengan rincian sebagai berikut:

CN201 diberi nama READER adalah konektor yang digunakan untuk antarmuka dengan pembaca kartu. Konektor ini sudah dilengkapi dengan power suplai 12 volt dan masukan D0 dan D1.

CN202, DOOR IN adalah konektor untuk masukan yang berhubungan dengan pintu. DS adalah Door Sensor yang berfungsi mendeteksi kondisi buka tutup pintu dan bisa menggunakan sensor berbentuk magnetic contact. Jika tidak digunakan maka masukan DS bisa dihubung singkat dengan GND. DE adalah Door Exit yang dihubungan dengan tombol tekan atau push button yang berfungsi untuk membuka pintu dari dalam.

CN203, SW OUT adalah konektor keluaran dari kontak relay yang dihubungkan dengan electric lock atau kunci elektrik. Koneksinya tergantung dari jenis kunci yang digunakan bisa jenis fail safe dihubungkan ke NC atau fail secure dihubungkan ke NO. Instalasinya bisa dilihat pada gambar berikut:



CN204, SERIAL adalah konektor untuk antarmuka dengan RS-232 dan dapat dihubungkan langsung dengan gerbang COM pada PC. Agar dapat berkomunikasi dengan PC maka diperlukan aplikasi yang harus dijalankan pada PC. Untuk komunikasi dengan PC maka pada postingan kali ini belum akan aku bahas. Pembahasan akan dilakukan pada postingan yang akan datang. Jadi rangkaian yang berkaitan dengan P3.0/RXD dan P3.1/TXD di atas untuk sementara diabaikan dulu. Karena pembahasan termasuk program yang harus dijalankan pada PC yang dibuat dengan Visual Basic.

Sabar yaaa....

CN205, POWER adalah konektor yang dihubungkan dengan power suplai dengan sumber tegangan sebesar 12 volt.

JP201, PRG/RUN adalah pemintas atau jumper yang digunakan untuk menentukan status program dari panel kita. Menghubung-singkatkan JP201 ke GND akan memerintahkan mikrokontroler untuk menjalankan menu pemrograman kartu. Sementara agar sistem kita berjalan sebagai pintu akses maka dibiarkan terbuka.

S201, UNIT ID adalah saklar dip yang berfungsi menetapkan nomor dari unit atau perangkat yang dibutuhkan nantinya sebagai penomoran perangkat dalam sebuah jaringan. Dari jumlah bit S201 maka jumlah maksimal perangkat dalam sebuah jaringan adalah 16 unit dimulai dari 00H sampai dengan 0FH. Jadi sama dengan SERIAL nanti.

Untuk menyimpan banyaknya data kartu yang digunakan kita menggunakan EEPROM AT93C46 yang memiliki kapasitas 1k bit atau 128 byte. Panjang data dari format Wiegand 26 bit adalah 3 byte ditambah 1 byte untuk status maka maksimal data kartu yang dapat disimpan adalah 32 kartu. Pada postingan kali ini, aku akan menggunakan seluruh kapasitas EEPROM hanya untuk menyimpan data kartu dengan panjang data 3 byte.

Selanjutnya, supaya alat bisa berfungsi, isi dengan program berikut:

$mod51

PinProgram        bit   p1.4
DIO               bit   p1.5
CLK               bit   p1.6
RST               bit   p1.7
DoorSensor        bit   p3.2
DoorExit          bit   p3.3
WiegandData0      bit   p3.4
WiegandData1      bit   p3.5
DoorRelay         bit   p3.7

DataHeksa         data  08h
Bendera           data  20h
      Fail  bit   Bendera.0

Pertama sobat paling tidak harus menetapkan parameter seperti di atas yang akan digunakan dalam listing program nantinya untuk mempermudah dalam penulisannya. Parameter harus sesuai dengan gambar rangkaian yang dibuat.

org   0h
      acall ResetChip
      jnb   PinProgram, DefaultUnit
      ajmp  AppMulai

DefaultUnit:
      mov   r5, #20

Default2:
      mov   r6, #200

Default2:
      mov   r7, #250
      clr   DoorRelay

TungguPinProgram:
      jb    PinProgram, AppMulai
      djnz  r7, TungguPinProgram
      djnz  r6, Default2
      djnz  r5, Default1
      clr   DoorRelay
      jnb   PinProgram, $
      acall AT93C46_EWEN
      acall AT93C46_ERAL
      acall AT93C46_EWDS
      acall Pulsa1Detik
      setb  DoorRelay

Pada awal program alamat 0000H dimulai dengan me-reset EEPROM AT93C46 agar pin RST menjadi rendah. Kemudian program akan memeriksa status PinProgram untuk tujuan default unit atau reset pabrik (factory reset) jika bit tersebut rendah.

Sebelum memastikan pelaksanaan reset unit, sebelumnya program akan menjalankan perintah tunggu menggunakan register R5, R6 dan R7 yang dioperasikan sebagai pecacah mundur menggunakan perintah DJNZ. Dari nilai yang diisikan pada register-register tersebut dapat dihitung perkiraan waktu tuda selama 4 detik sambil memeriksa apakah status PinProgram dalam keadaan rendah atau tidak. Jika PinProgram tinggi sebelum pencacah selesai maka reset unit dibatalkan.

Jika pencacah mundur selesai dan PinProgram masih rendah, maka program akan mengaktifkan relay dengan perintah CLR dan menunggu sampai PinProgram menjadi tinggi sebelum melaksanakan penghapusan isi memori AT93C46 dengan instruksi ERAL (erase all). Setelah selesai, program kembali menon-aktifkan relay setelah 1 detik.

AppMulai:
      jnb   PinProgram, SubProgram
      jb    DoorSensor, AppMulai
      jnb   DoorExit, AppBukaPintu
      jnb   WiegandData0, AppBacaKartu
      jnb   WiegandData1, AppBacaKartu
      ajmp  AppMulai


Selanjutnya aplikasi akses pintu dimulai dari AppMulai. Pertama adalah memeriksa status PinProgram, jika rendah akan menuju alamat SubProgram. Kedua memeriksa status DoorSensor, jika tinggi akan kembali ke AppMulai. Ketiga memeriksa status DoorExit, jika rendah akan menuju ke AppBukaPintu. Terakhir adalah memerika WiegandData 0 dan 1, jika salah satu rendah akan menuju AppBacaKartu.

SubProgram:
      clr   DoorRelay

AppProgram:
      jb    PinProgram, AppMulai
      jnb   WiegandData0, ProgramKartu
      jnb   WiegandData1, ProgramKartu
      ajmp  AppProgram

Alamat SubProgram diawali dengan mengaktifkan relay kemudian menjalankan rutin AppProgram.

Pada AppProgram berisi perintah memeriksa status PinProgram, tinggi tinggi maka akan kembali ke AppMulai. Kemudian diteruskan dengan memeriksa masukan Wiegand. Jika salah satu dari bit data Wiegand rendah maka selanjutnya adalah menjalankan rutin ProgramKartu.

ProgramKartu:
      mov   r1, #DataHeksa
      acall Wiegand
      acall CekWiegand
      jnz   PrgMemori
      ajmp  AppProgram

Pada rutin ProgramKartu, register R1 diisi dengan alamat buffer DataHeksa untuk kemudian memanggil subrutin membaca kartu RFID. Setelah pembacaan selesai sobat perlu memeriksa isi dari buffer, jika tidak kosong maka dapat dilanjutkan ke PrgMemori jika ternyata kosong dan berarti ada kesalahan maka kembali ke AppProgram.

Berikut adalah rutin PrgMemori yang berfungsi mengisi data kartu ke memori AT93C46.

PrgMemori:
      mov   dph, #0
      mov   dpl, #0
      mov   r7, #32

PrgIsiMemori:
      acall AT93C46_READ
      mov   r6, #3
      cpl   a
      jnz   PrgIsiMemoriBerikut
      setb  DoorRelay
      mov   r0, #DataHeksa
      acall AT93C46_EWEN
      mov   a, #9

PrgSimpanKartu:
      acall AT93C46_WRITE
      mov   a, @r0
      inc   dptr
      inc   r0
      djnz  r6, PrgSimpanKartu
      acall AT93C46_EWDS
      acall Pulsa1Detik
      ajmp  SubProgram

PrgIsiMemoriBerikut:
      inc   dptr
      djnz  r6, PrgIsiMemoriBerikut
      inc   dptr
      djnz  r7, PrgIsiMemori
      ajmp  AppProgram

Pertama-tama rutin menetapkan alamat memori dengan register DPTR dengan 0000H atau alamat awal dari memori. Kemudian seperti sudah dijelaskan di bagian atas postingan ini maka register R7 diisi dengan nilai maksimum dari jumlah kartu yang memungkinkan yaitu 32 kartu.

Rutin PrgIsiMemori, pertama-tama membaca isi AT93C46 sesuai dengan alamat pada register DPTR dengan memanggil sub rutin AT93C46_READ. Disini aku menyisipkan perintah mengisi register R6. Akumulator sekarang berisi data sesuai alamat DPTR dan kemudian dikomplemen dengan perintah CPL, jika akumulator tidak kosong atau isi pada memori adalah FFH maka program akan melompat ke PrgIsiMemoriBerikut untuk menuju alamat memori berikutnya.

Jika memori masih kosong maka data Wiegand dapat disimpan. Untuk memberi indikator maka aku menggunakan perintah menon-aktifkan Relay. Kemudian mengisi register R0 dengan bufer DataHeksa, menjalankan sub rutin AT93C46_EWEN untuk membolehkan menulis ke memori dan menetapkan isi akumulator dengan nilai #09H.

Rutin PrgSimpanKartu, pertama-tama adalah mengisi memori dengan nilai akumulator 09H. Setelah menyalin isi buffer DataHeksa melalui register penunjuk R0 selanjutnya menaikan isi register DPTR dan R0 sebelum akhirnya memeriksa isi register R6 dengan DJNZ.  Karena isi register R6 semula adalah 3 maka program akan mengulangi rutin PrgSimpanKartu sebanyak 3 kali untuk memindahkan isi buffer DataHeksa sebanyak 3 byte sesuai data kartu ke memori.

Setelah data kartu tersimpan maka selanjutnya adalah menon-aktifkan EEPROM agar tidak dapat ditulis dengan memanggil sub rutin AT93C46_EWDS. Kemudian program diakhiri dengan menjalankan timer selama 1 detik sebelum kembali ke rutin SubProgram.

Rutin PrgMemoriBerikut digunakan untuk menuju memori berikutnya sesuai sisa nilai register R6. Total lompatan alamat DPTR menuju ke alamat berikutnya adalah DPTR+4, maka jika semula nilai DPTR adalah 0000H maka setelah rutin ini akan bernilai 0004H. Rutin ini juga memeriksa nilai register R7 untuk memastikan pembacaan tidak melebihi 32 atau DPTR menjadi 80H karena lokasi alamat terakhir AT93C46 adalah 7FH.

Berikut adalah rutin AppBukaPintu yang berfungsi mengaktifkan pulsa selama 5 detik untuk membuka pintu.

AppBukaPintu:
      clr   DoorRelay
      acall Pulsa5Detik
      setb  DoorRelay
      ajmp  AppMulai

Rutin AppBukaPintu dijalankan karena bila mendeteksi bit DoorExit rendah atau tombol ditekan. Setelah mengaktifkan relay untuk membuka pintu selanjutnya program menjalankan tundaan selama 5 detik sebelum akhirnya menon-aktifkan kembali relay dan kembali ke rutin AppMulai.

Berikut adalah AppBacaKartu yang berfungsi membaca kartu kemudian memeriksa nomor kartu tersebut pada daftar memori At93C46.

AppBacaKartu:
      mov   r0, #DataHeksa
      acall Wiegand
      acall CekWiegand
      jnz   BacaMemori
      ajmp  AppMulai

Setelah pada rutin AppMulai terdeteksi salah satu bit WiegandData berstatus rendah maka rutin AppBacaKartu akan memanggil sub rutin membaca Wiegand dan menyimpannya pada buffer DataHeksa. Jika data terbaca valid atau benar maka selanjutkan akan dibandingkan dengan isi EEPROM.

BacaMemori:
      mov   dph, #0
      mov   dpl, #0
      mov   r7, #32

BacaIsiMemori:
      acall AT93C46_READ
      cpl   a
      jnz   BacaMemoriBerikut
      ajmp  AppMulai

Pertama data Wiegand Pada buffer DataHeksa akan dibandingkan dengan alamat EEPROM 0000H sesuai ditentukan pada perintah rutin BacaMemori sesuai isi register DPTR. Pada rutin ini kembali register R7 diisi dengan nilai maksimum kartu yang dapat disimpan pada EEPROM yaitu 32.

Selanjutnya rutin BacaIsiMemori memeriksa byte pertama yang berisi status isi dari alokasi memori kartu pada EEPROM. Jika kosong maka program akan kembali menuju AppMulai.

BacaMemoriBerikut:
      mov   r0, #DataHeksa
      mov   r6, #3

CekIsiMemori:
      inc   dptr
      acall AT93C46_READ
      xch   a, b
      mov   a, @r0
      inc   r0
      xrl   a, b
      jnz   CekIsiBerikut
      djnz  r6, CekIsiMemori
      ajmp  AppBukaPintu

CekIsiBerikut:
      inc   dptr
      djnz  r6, CekIsiBerikut
      djnz  r7, BacaIsiMemori
      ajmp  AppMulai

Rutin BacaMemoriBerikut adalah rutin untuk membandingkan data buffer melalui register R0 dengan isi EEPROM sepanjang 3 byte yang ditetapkan sesuai isi register R6.

Setelah register R0 dan R6 ditetapkan maka selanjutnya mulai membaca isi EEPROM satu pertsatu dengan memanggil sub rutin AT93C46_READ dan menyimpannya di akumulator. Pencocokan isi kemudian dilakukan dengan menukar isi akumulator dengan register B dengan perintah XCH (Exchange register) kemudian menyalin buffer sesuai isi register R0 ke akumulator dan melaksanakan perintah XOR (exclusive OR) terhadap akumulator dan register B. Jika hasilnya isi akumulator kosong maka berarti sama dan rutin CekIsiMemori akan diulangi untuk alamat berikutnya dan jika ke-3 byte sama maka program akan menjalankan rutin AppBukaPintu karena nomor kartu terbaca terdaftar dalam memori. Bahasa kerennya access granted.

Jika byte data dari DataHeksa dan alokasi data di EEPROM tidak sama maka program akan melanjutkan ke alokasi memori berikutnya dengan melaksanakan perintah CekIsiBerikut yang menghiitung posisi alamat berikut dari DPTR.

Berikut adalah sub rutin pewaktu 5 detik dan 1 detik yang merupakan satu kesatuan.

Pulsa5Detik:
      mov   r5, #50
      ajmp  PulsaReg6

Pulsa1Detik:
      mov   r5, #10

PulsaReg6:
      mov   r6, #200

PulsaReg7:
      mov   r7, #250
      djnz  r7, $
      djnz  r6, PulsaReg7
      djnz  r5, PulsaReg6
      ret

sub rutin Pulsa5Detik menetapkan isi register R5 dengan nilai 50 kemudian melompat ke PulsaReg6. Sementara Pulsa1Detik menetapkan register R5 dengan 10.

Pada PulsaReg6 dan seterusnya, program berisi perintah mengisi register R6 dengan nilai 200 dan pada rutin PulsaReg7 mengisi register R7 dengan 250. Dengan menggunakan perintah mencacah turun DJNZ maka nilai pulsa dapat dihitung.

Dimulai dari awal sub rutin Pulsa5Detik terdapat 4 perintah MOV Rn, # yang membutuhkan 1 siklus dengan waktu eksekusi kurang lebih 1us (pendekatan karena menggunakan kristal 11,095200MHz nilai sebenarnya adalah 1,085us) dan 1 perintah DJNZ R7 dengan 2 siklus maka dapat dihitung (250x2)+4=504 siklus. Kemudian DJNZ R6 dan MOV R7 dengan 3 siklus menjadi (504+3)x200=101400 siklus. Terakhir DJNZ R5 dengan siklus 3 menjadi (101400+3)x50=5.070.150us.

Pada program di atas terdapat perintah pemanggilan sub rutin CekWiegand untuk memeriksa isi data buffer DataHeksa. Sub rutin tersebut seperti di bawah ini:

CekWiegand:
      mov   r0, #DataHeksa
      mov   r7, #3

CekIsiWiegand:
      mov   a, @r0
      jnz   CekWiegandOK
      inc   r0
      djnz  r7, CekIsiWiegand

CekWiegandOK:
      ret

Setelah menetapkan register R0 untuk merepresentasi alamat RAM buffer DataHeksa dan panjabng data 3 byte maka perintah loop akan memeriksa isi buffer. Jika salah satu dari isi buffer tersebut tidak kosong maka dianggap data benar atau valid.

$include (c:\tesasm\wiegand.txt)
$include (c:\tesasm\93C46_8.txt)

end

Program yang kita buat berkaitan dengan modul-modul yang diperlukan yaitu wiegand.txt yang berisi sub rutin perintah membaca data wiegand dan 93c46_8.txt yang merupakan modul antarmuka dengan EEPROM AT93C46 dengan format data 8 bit.



Udah ya, makasih udah baca postingan aku. Semoga bisa bermanfaat, sukur-sukur bisa diterapkan di rumah sobat semua.

Salam....

Modul Aplikasi Untuk EEPROM Jenis AT93C46/56/66




Dalam rangkaian elektronika berbasis mikrokontroler yang dibuat, kadang-kadang sobat menggunakan keping memori untuk menyimpan data. Salah satu jenis memori yang sering dipakai adalah AT93C46, AT93C56 atau AT93C66. Ketiga jenis memori tersebut adalah satu rumpun. Dalam datasheet-nya disebut sebagai 3 Wire Serial EEPROMs atau EEPROM dengan penyemat antarmuka menggunakan 3 saluran/kabel. Konfigurasinya bisa dilihat di bawah ini:

  
Selain Vcc dan Gnd ada penyemat atau pin lain yang digunakan untuk antar muka dengan mikrokontroler yaitu pin 1 CS (chip select), 2 SK (serial clock) serta pin 3 dan 4 DI (data input) dan DO (data output). Pin 3 dan 4 dalam aplikasinya selalu dijadikan satu. Sementara pin 6 (ORG) bisa dihubungkan ke Vcc untuk format data 16 bit atau ke Gnd untuk format data 8 bit.

Meskipun satu rumpun, AT93C46/56/66 memiliki perbedaan yang terutama adalah kapasitas memorinya. AT93C46 berkapasitas 1k bit atau 128 byte atau 64 word (1 word = 16 bit). Sementara AT93C56 berkapasitas 2k bit atau 256 byte atau 128 word dan AT93C66 berkapasitas 4 k bit atau 512 byte atau 256 word.

Untuk penjelasan lebih rinci dapat dilihat pada datasheet untuk AT93C46/56/66 yang bisa diunggah lewat internet. Soalnya bisa kepanjangan nih kalau dibahas di sini. Di sini akan dibahas soal modul aplikasi yang biasa aku pakai sebagai peranti lunak antar-muka dengan AT93C46/56/66.

Modul yang akan diuraikan berisi perintah-perintah yang sesuai dengan instruksi dalam AT93C yaitu: READ, WRITE, EWEN (erase/write enable), EWDS (erase/write disable), ERASE, ERAL (erase all) dan WRAL (write all).

Tapi sebelum menjalankan semua instruksi di atas ada beberapa instruksi pendukung dan parameter yang akan dijelaskan sebagai berikut:

RST   bit   p3.4
CLK   bit   p3.5
DIO   bit   p3.7

Flag        data  20h
      Fail  bit   Flag.0

Pastikan baris-baris parameter di atas ditulis pada bagian awal program. Tiga baris pertama untuk menetapkan konfigurasi gerbang sebagai antar-muka yang terhubung ke AT93Cxx. Gerbang yang tertulis di atas seperti P3.4, P3.5 dan P3.7 tidaklah mutlak, terserah saja, tergantung rangkaian yang sobat buat. Yang terpenting adalah penetapan parameter RST, CLK dan DIO. Kalau ini tidak ditetapkan maka saat membuat program dapat langsung ditulis nama gerbangnya, namun pengalamanku kadang suka lupa fungsi dari gerbang yang digunakan.

Selanjutnya menetapkan register dengan nama Flag yang diletakkan pada alamat 20H dari RAM dan pada register tersebut menetapkan bit Flag.0 sebagai bit Fail. Alamat 20H tidak mutlak tetapi tidak semua register dalam RAM bisa dibuat seperti ini.

Aplikasi Me-RESET EEPROM Seri AT93Cxx

ResetChip:
      clr   CLK
      setb  RST
      clr   RST
      ret

Yang pasti untuk mereset AT93C adalah dengan memberikan kondisi rendah pada pin CS dengan CLR RST. Tapi karena AT93C melaksanakan instruksi pada tepi naik masukan SK maka sekalian saja dikondisikan rendah dengan CLR CLK.

Prosedur yang penting dalam penangan sebuah memori yang bekerja secara serial adalah mempersiapkan program yang berisi perintah untuk menulis dan membaca data secara serial bit per bit. Berikut kita mulai dari subrutin menulis ke dalam AT93C.

WriteSerialBit:
      push  acc
      push  07H
      mov   R7, #8

NxtWRBit:
      rlc   A
      jc    WRBitH

WRBitL:
      clr   DIO
      ajmp  WRClk

WRBitH:
      setb  DIO

WRClk:
      clr   CLK
      setb  CLK
      djnz  R7,NxtWRBit
      pop   07H
      pop   acc
      ret

Perintah di awali dengan mengamankan isi akumulator dan register R7 yang digunakan pada rutin WriteSerialBit. Selanjutnya menetapkan isi register R7 dengan nilai 8H sesuai dengan jumlah bit dalam byte. Akumulator adalah register yang berisi data yang akan diproses. Untuk mengirimkan isi bit per bit dari akumulator digunakan perintah RLC (rotate to left with carry). AT93C memproses data dari MSB maka pertama kali perintah RLC dilaksanakan maka bit carry akan berisi bit ACC.7 dari akumulator. Program kemudian akan bercabang sesuai kondisi bit carry, jika rendah maka menjalankan perintah agar DI juga rendah. Sebaliknya jika bit carry tinggi maka pin DI akan dibuat tinggi pula.

Agar data pada DI diproses oleh AT93C maka selanjutnya dilaksanakan perintah untuk membangkitkan pulsa CS dengan perintah CLR dan SETB secara berurutan. Proses akan dikerjakan pada tepi naik dari sinyal CS.

Perintah akan diulang sebanyak 8 kali dengan perintah DJNZ sebelum diakhiri dengan mengembalikan isi register R7 dan akumulator, kemudian menjalan perintah RET.

Selanjutnya kita akan membahas subrutin membaca bit per bit secara serial dari AT93C.

ReadSerialBit:
      push  07H
      clr   a
      setb  DIO
      mov   R7, #8

RDClk:
      clr   CLK
      setb  CLK
      jb    DIO,RDBitH

RDBitL:
      clr   c
      ajmp  ShiftInBit

RDBitH:
      setb  c

ShiftInBit:
      rlc   a
      djnz  R7,RDClk
      pop   07H
      ret

Baris pertama adalah mengamankan isi register R7 diikuti mengosong register akumulator yang nanti akan dijadikan tempat menyimpan data yang dibaca. Kemudian kita perlu memastikan kondisi DO dalam keadaan tinggi. Setelah itu menetapkan banyaknya bit yang akan dibaca dengan mengisi register r7 dengan nilai 8.

Setelah memberikan sinyal pada SK perintah selanjutnya adalah memeriksa kondisi pin DO, jika tinggi program bercabang ke perintah agar bit carry tinggi, sebaliknya jika DO rendah maka bit carry juga dibuat rendah.

Selanjutnya adalah melaksanakan perintah untuk merotasi akumulator ke kiri diikuti dengan carry.

Setelah kemudian mengulangi perintah membaca DO sebanyak 8 kali, subrutin diakhiri dengan mengembalikan isi register R7.

Subrutin berikut adalah untuk memeriksa status READY/BUSY dari pin DO terutama pada perintah-perintah seperti menulis dan menghapus.

CheckEEPROM:
      push  07H
      push  05H
      mov   R6, #2
      mov   R7, #255
      clr   Fail
      setb  DIO
      clr   RST
      setb  RST

Subrutin diawali dengan mengamankan register-register R6 dan R7 untuk kemudian mengisi register-register tersebut untuk menentukan lamanya tundaan waktu tunggu selama proses internal dalam serpih AT93C. Proses dimulai dengan memberikan pulsa rendah pada pin CS dengan perintah CLR dan SETB berturut-turut setelah sebelumnya memastikan bit Fail pada keadaan rendah dan pin DO tinggi.

WaitBusy:
      clr   CLK
      setb  CLK
      jb    DIO, WaitTimer1
      mov   R6, #2
      mov   R7, #255
      ajmp  Busy

WaitTimer1:
      djnz  R7, WaitBusy
      mov   R7, #255
      djnz  R6, WaitBusy
      setb  Fail
      ajmp  Ready

Rutin WaitBusy berisi perintah menunggu sampai kondisi pin DO menjadi rendah dengan perintah JB sebagai indikasi keadaan BUSY. Setelah menjalankan perintah memberi pulsa pada SK, rutin program memeriksa kondisi DO, jika tinggi maka rutin tunggu WaitTimer1 dilaksanakan yang ditentukan sesuai register R5 dan R7 dari nilai register tersebut menghasilkan waktu tunggu selama 3ms.

Jika sampai batas waktu pin DO tidak juga rendah maka selanjutnya rutin akan mengaktifkan bit Fail. Tetapi jika dijumpai pin DO rendah makan selanjutnya ke rutin WaitReady yaitu menunggu pin DO kembali tinggi. Di sini isi register R6 dikembalikan ke nilai 2 seperti semula.

WaitReady:
      clr   CLK
      setb  CLK
      jnb   DIO, WaitTimer2
      ajmp  Ready

WaitTimer2:
      djnz  R7, WaitReady    
      mov   R7, #255
      djnz  R6, WaitReady
      setb  Fail

Rutin WaitReady hampir sama dengan WaitBusy, perbedaannya hanya menunggu pin DO menjadi tinggi dengan perintah JNB.

Ready:
      pop   06H
      pop   07H
      ret

Baik sukses atau tidak yang ditandai dengan bit Fail, akhirnya subrutin diakhiri dengan mengembalikan isi register R6 dan R7 sebelum keluar dengan perintah RET.

Nah, biar sobat lebih memahami bagaimana proses tersebut, aku lampirkan nih salah satu diagram pewaktuan yang menunjukkan status READY/BUSY yaitu perintah WRITE. Hal seperti ini juga berlaku pada perintah WRAL, ERASE dan ERAL


Dari datasheet, karakteristik untuk nilai tWP normalnya adalah sekitar 3ms dan maksimal 10ms. Untuk perintah lainnya bisa sobat lihat pada datasheet AT93C46/56/66.

Nah, keempat subrutin di atas yaitu ResetChip, WriteSerialBit, ReadSerialBit dan CheckEEPROM selanjutnya berlaku untuk semua jenis memori baik AT93C46, AT93C56 maupun AT93C66. Selanjutnya sobat akan aku jelaskan tentang 7 perintah yang ada pada memori seri AT93Cxx.


Di atas adalah diagram perintah untuk AT93C46. Untuk menjalan sebuah perintah di atas maka pertama harus memberikan bit dengan logika 1 sebagai MSB pada DI untuk menetapkan start bit (SB). Berikutnya sobat bisa menentukan 2 bit operation code (op code). Untuk perintah READ, ERASE dan WRITE, setelah op code dapat langsung diisi dengan lokasi alamat memori yang akan diproses. Sementara untuk perintah EWEN, ERAL, WRAL dan EWDS maka 2 bit berikutnya adalah op code untuk masing-masing dan bit-bit LSB sisanya diabaikan tapi tetap harus diisi dan diberikan ekstra pulsa. Perintah di atas juga berlaku untuk AT93C56 dan AT93C66 tetapi perbedaannya adalah pada jumlah bit-bit alamat yang dimiliki.


Dari tabel di atas memperlihatkan jika alamat untuk AT93C46 adalah 7 bit (A6 – A0) untuk format 8 bit atau 6 bit (A5 – A0) untuk format 16 bit, sementara untuk AT93C56/66 adalah 9 bit (A8 – A0) atau 8 bit (A7 – A0) untuk format 16 bit. Sebenarnya untuk AT93C55 bit yang berlaku hanya 8 bit untuk format 8 bit atau 7 bit untuk format 16 bit tetapi bit tambahan tersebut tetap harus diproses meski sebenarnya tidak ada atau diabaikan karena kita tentu hanya akan menentukan alamat sesuai dengan kapasitas yang disediakan.

Nah, sekarang sobat pastinya tahu bahwa ada beberapa perbedaan yang harus kita ketahui dalam merancang sebuah modul antar muka dengan AT93C46/56/66.

Perbedaan pertama antara adalah panjang alamat dari masing-masing jenis dan untuk ini aku klasifikasikan menjadi 2 yaitu untuk AT93C46 memiliki 7 bit alamat sementara AT93C56/66 memiliki 9 bit alamat. Perbedaan kedua yang berlaku dalam organisasi data yang terdiri dari 2 yaitu format 8 bit dan 16 bit yang ditetapkan dengan pin ORG.

Dari gambar Write Timing dan tabel Instruction Set di atas dapat kita pahami urutan serial bit yang dioperasikan pada antarmuka seri AT89C, yaitu:

  • 1 bit SB (start bit)
  • 2 bit operation code
  • Bit alamat yang banyaknya sesuai dengan kapasitas memori.

Berdasarkan tabel Instruction Set dan Organization Key di atas dapat kita ketahui banyaknya bit untuk instruksi dan alamat yang dibutuhkan, yaitu:

  • 9 bit untuk AT93C46 pada format 16 bit data
  • 10 bit untuk AT93C46 pada format 8 bit data
  • 11 bit untuk AT93C56/66 pada format 16 bit data
  • 12 bit untuk AT93C56/66 pada format 8 bit data

Dari pembagian di atas menunjukkan bahwa format bit perintah berjumlah lebih dari 1 byte atau 8 bit.  Dan karena laju serial data antara pengiriman bit alamat dan saat pengiriman atau penerimaan bit data dilaksanakan secara langsung tanpa jeda maka berikut ini aku buat format data untuk byte MSB dan LSB yang nanti digunakan untuk mengirim perintah dan alamat, yaitu:

  • 0000000S – CCAAAAAA untuk AT93C46 pada format 16 bit data
  • 000000SC – CAAAAAAA untuk AT93C46 pada format 8 bit data
  • 00000SCC – AAAAAAAA untuk AT93C56/66 pada format 16 bit data
  • 0000SCCA – AAAAAAAA untuk AT93C56/66 pada format 8 bit data

Keterangan:

  • Pada MSB ditambahkan beberapa bit berlogika rendah untuk mengisi kekosongan menunggu logika tinggi dari start bit (SB).
  • S adalah bit SB
  • C adalah bit operation code
  • A adalah bit-bit alamat

Sekarang kita lihat program yang terdiri dari sub rutin untuk melaksanakan 7 perintah operasi dalam rumpun AT93C46/56/66.


Operasi READ

;Input  : DPTR = Address
;Output : A = Data
;         B = Data MSB

Pada operasi READ, sub rutin diarahkan untuk membaca data pada lokasi yang ditunjukkan oleh register DPTR yang terdiri dari DPH dan DPL. Byte data disimpan pada akumulator. Sementara untuk operasi 16 bit maka data MSB disimpan di register B.

AT93C46_READ:
      push  07H
      push  06H
      mov   R6, #2
      mov   R7, #255
      clr   Fail
      setb  RST

Penulisan AT93C46_READ dapat diganti dengan serpih memori yang digunakan seperti AT93C56_READ atau AT93C66_READ.

Sub rutin diawali dengan perintah mengamankan register R6 dan R7 dan mengganti dengan nilai untuk waktu tunggu. Kemudian dilanjutkan perintah me-reset bit Fail dan mengeset pin CS dengan perintah SETB RST.

      mov   a,DPH
      anl   a, #00000001B
      orl   a, #00001100B

Akumulator menyalin isi register DPH kemudian memprosesnya dengan operasi AND dan OR.

Ke 3 baris di atas tidak ada dalam AT93C46_READ dan hanya berlaku untuk sub rutin yang dijalankan pada AT93C56/66 dalam format 8 bit. Ke 3 baris tersebut diganti dengan:

      mov   a, #00000001B

Data akumulator di atas untuk AT93C46 dengan format 16 bit. Untuk format 8 bit diganti dengan #00000011B. Sementara untuk AT93C56/66  format 16 bit diganti dengan #00000110B.

Setelah akumulator berisi byte MSB, perintah selanjutnya adalah memproses akumulator dengan memanggil sub rutin WriteSerialBit seperti ditunjukkan pada perintah berikut.

      acall WriteSerialBit
      mov   a, DPL
      anl   a, #00111111B
      orl   a, #10000000B
      acall WriteSerialBit
      setb  DIO

Setelah byte MSB pada akumulator selesai diproses, dilanjutkan dengan menyalin DPL ke akumulator dan memprosesnya dengan operasi AND dan OR. Akumulator yang sudah berisi op code diproses dengan WriteBitSerial dan program di atas diakhiri dengan mengeset bit DIO menjadi tinggi.

Seperti sebelumnya, perintah di atas adalah untuk AT93C46 dengan format 16 bit data. Untuk format 8 bit, data untuk operasi AND diganti dengan #01111111B dan perintah ORL dihilangkan. Sementara pada antarmuka dengan AT93C56/66 bahkan kedua operasi AND dan OR di atas dihilangkan.

Dummy:
      jb    DIO, WaitTimer3
      ajmp  DataReady

WaitTimer3:
      djnz  R7,Dummy   
      mov   R7, #255
      djnz  R6,Dummy
      setb  Fail
      ajmp  EndReadEEPROM

Setelah bit-bit SB, Op Code dan alamat dikirim, program akan memeriksa status dummy bit berlogika rendah yang dikirim oleh DO dari AT93Cxx. Status diperiksa menggunakan perintah JB dengan lama waktu tunggu menurut isi register R6 dan R7 adalah sekitar 2ms. Jika dummy bit tidak muncul hingga pencacah habis maka rutin akan mengeset bit Fail dan keluar. Tapi jika dummy bit ada maka rutin selanjutnya akan membaca bit-bit data dengan sub rutin ReadSerialBit.

DataReady:
      acall ReadSerialBit
      xch   a, b
      acall ReadSerialBit

Pemanggilan sub rutin ReadSerialBit pertama adalah untuk membaca MSB dari memori yang selanjutnya di pindahkan ke register B sebagai data MSB dengan perintah XCH di mana isi akumulator bertukar tempat dengan register B.

Untuk operasi dengan format data 8 bit maka 2 baris terakhir di atas yaitu XCH A,B dan ACALL ReadSerialBit kedua tidak diperlukan.

EndReadEEPROM:
      clr   RST
      pop   06H
      pop   07H
      ret

Sub rutin AT93C46_READ diakhiri dengan me-reset CS dan mengembalikan isi register R6 dan R7.

Perihal dummy bit dapat dilihat dari diagram pewaktuan seperti ditunjukkan di bawah ini:




Operasi WRITE

;Input : DPTR = Address
;        A = Data
;        B = Data MSB

Operasi WRITE untuk menulis data ke lokasi memori yang ditunjukkan oleh DPTR di mana akumulator untuk LSB dan pada operasi 16 bit register B untuk data MSB.

AT93C46_WRITE:
      push  acc
      push  b
      setb  RST

Program untuk AT93C56/66 dalam format 8 bit adalah sebagai berikut:

      mov   a,DPH
      anl   a, #00000001B
      orl   a, #00001010B

Untuk AT93C46 dengan format 16 bit ketiganya diganti dengan:

      mov   a, #00000001B

Untuk format 8 bit diganti dengan #00000010B. Sementara untuk AT93C56/66 format 16 bit diganti dengan #00000101B

      acall WriteSerialBit
      mov   a,DPL
      anl   a, #00111111B
      orl   a, #01000000B
      acall WriteSerialBit

Perintah di atas untuk AT93C46 format 16 bit data. Untuk 8 bit perintah AND dihilangkan dan operasi ORL diganti dengan #10000000B. Pada antarmuka AT93C56/66 kedua operasi AND dan OR dihilangkan.

      pop   acc
      acall WriteSerialBit
      pop   acc
      acall WriteSerialBit

Perintah pada 2 baris pertama adalah untuk menulis ke memori register B yang tadi disimpan di stack sebagai data MSB dan 2 baris perintah berikutnya untuk menulis data LSB dari akumulator. Untuk operasi 8 bit maka 2 baris terakhir dihilangkan.

      acall CheckEEPROM
      clr   RST
      ret

Sub rutin AT93C46_WRITE diakhiri dengan memeriksa status READY/BUSY dengan memanggil sub rutin CheckEEPROM kemudian dengan perintah CLR untuk membuat pin CS rendah dan diakhiri dengan RET.


Operasi ERASE

;Input : DPTR = Address

Operasi ERASE pada dasarnya berisi baris perintah hampir sama dengan operasi WRITE hanya saja tidak membutuhkan register untuk data dan sudah tentu menggunakan op code yang berbeda.

AT93C46_ERASE:
      setb  RST

Program untuk AT93C56/66 dalam format 8 bit adalah sebagai berikut:

      mov   a,DPH
      anl   a, #00000001B
      orl   a, #00001110B

Untuk AT93C46 dengan format 16 bit ketiganya diganti dengan:

      mov   a, #00000001B

Untuk format 8 bit diganti dengan #00000011B. Sementara untuk AT93C56/66 format 16 bit diganti dengan #00000111B

      acall WriteSerialBit
      mov   a,DPL
      orl   a, #11000000B
      acall WriteSerialBit

Perintah di atas untuk AT93C46 format 16 bit data. Untuk 8 bit data operasi ORL diganti dengan #10000000B. Pada antarmuka AT93C56/66 operasi OR dihilangkan. Setelah mengirim alamat, sub rutin dikahiri dengan memanggil sub rutin CheckEEPROM untuk memeriksa status READY/BUSY.

      acall CheckEEPROM
      clr   RST
      ret



Operasi EWDS

Sub rutin AT93C46_EWDS adalah perintah untuk operasi EWDS yang berisi perintah erase and write disable yaitu menon-aktifkan seluruh perintah pemrograman baik menulis atau menghapus data pada serpih memori. Rincian sub rutin ini sebagai berikut:

AT93C46_EWDS:
      setb  RST
      mov   a, #00000001B
      acall WriteSerialBit
      mov   a, #00000000B
      acall WriteSerialBit
      clr   RST
      ret

Operasi EWDS, pemanggilan sub rutin WriteSerialBit yang pertama untuk mengirim data akumulator berisi perintah MSB dan sub rutin WriteSerialBit kedua mengirim LSB-nya. Sub rutin AT93C46_EWDS di atas untuk AT93C46 format 16 bit data. Untuk format 8 bit isi akumulator untuk MSB harus berisi #00000010B. Untuk AT93C56/66 format 16 bit diganti dengan #00000100B dan untuk 8 bitnya #00001000B. Untuk LSB-nya tidak ada perubahan.



Operasi EWEN

Operasi EWEN memiliki urutan yang sama dengan EWDS di atas. Yang membedakan adalah isi dari akumulator untuk perintah MSB dan LSB-nya dan sudah barang tentu penamaannya diganti pula menjadi....

AT93C46_EWEN:

Isi akumulator MSB untuk operasi EWEN sama kecuali untuk AT93C56/66 format 8 bit harus diganti #00001001B.

Sementara pada operasi sub rutin WriteSerialBit kedua untuk LSB-nya, pada AT93C46 format 16 bit data isi akumulator diganti dengan #00110000B dan untuk format 8 bit dengan #01100000B. Sementara untuk AT93C56/66 format 16 bit diganti dengan #11000000B dan untuk 8 bitnya #10000000B.


Operasi WRAL

;Input : A = Data
;        B = Data MSB

Operasi WRAL berfungsi mengisi data pada seluruh lokasi memori. Sub rutin AT93C46_ERAL akan memindahkan data pada akumulator pada seluruh lokasi memori. Dan pada operasi 16 bit juga memindahkan data dari register B ke seluruh lokasi memori.

AT93C46_WRAL:
      push  acc
      push  b
setb  RST
      mov   a, #00000001B
      acall WriteSerialBit
      mov   a, #00010000B
      acall WriteSerialBit

Operasi WRAL pertama-tama mengamankan register akumulator dan register B. Untuk operasi dengan format 8 bit maka register B tidak digunakan dan perintah ini bisa dihilangkan.

Pemanggilan sub rutin WriteSerialBit pertama untuk mengirim data akumulator berisi perintah MSB dan sub rutin WriteSerialBit kedua mengirim LSB-nya. Sub rutin AT93C46_ERAL di atas untuk AT93C46 format 16 bit data. Pada format 8 bit-nya isi akumulator untuk MSB harus berisi #00000010B. Untuk AT93C56/66 format 16 bit MSB diganti dengan #00000100B dan untuk 8 bitnya #00001000B. Untuk data LSB pada AT93C46 format 8 bit isi akumulator diganti dengan #00100000B. Sementara pada AT93C56/66 format 16 bit akumulator untuk LSB diganti dengan #01000000B dan untuk format 8 bit-nya dengan #10000000B.

      pop   acc
      acall WriteSerialBit
      pop   acc
      acall WriteSerialBit
      acall CheckEEPROM
      clr   RST
      ret

Selanjutnya 2 baris program pertama di atas akan menyalin akumulator yang merupakan isi register B tersimpan untuk data MSB kemudian mengirimnya dengan sub rutin WriteSerialBit.

Perintah di atas dilaksanakan 2 kali kemudian menjalankan sub rutin memeriksa status READY/BUSY.

Untuk operasi dengan format data 8 bit maka 2 baris pertama di atas bisa dihilangkan.


Operasi ERAL

Operasi ERAL berfungsi menghapus seluruh isi dari lokasi memori.

AT93C46_ERAL:
      setb  RST
      mov   a, #00000001B
      acall WriteSerialBit
      mov   a, #00100000B
      acall WriteSerialBit
      acall CheckEEPROM
      clr   RST
      ret

Operasi ERAL, pemanggilan sub rutin WriteSerialBit pertama untuk mengirim data akumulator berisi perintah MSB dan sub rutin WriteSerialBit kedua mengirim LSB-nya. Sub rutin AT93C46_ERAL di atas untuk AT93C46 format 16 bit data. Pada format 8 bit-nya isi akumulator untuk MSB harus berisi #00000010B. Untuk AT93C56/66 format 16 bit MSB diganti dengan #00000100B dan untuk 8 bitnya #00001001B. Untuk data LSB pada AT93C46 format 8 bit isi akumulator diganti dengan #01000000B. Sementara pada AT93C56/66 format 16 bit akumulator untuk LSB diganti dengan #10000000B dan untuk format 8 bit-nya dengan #00000000B.

Setelah data perintah ERAL sudah dikirimkan ke serpih, maka selanjutnya memeriksa status READY/BUSY dengan CheckEEPROM yang diakhiri dengan CLR RST dan RET.

Demikian penjelasan dari Modul Aplikasi Untuk EEPROM Jenis AT93C46/56/66. Kesimpulan yang bisa sobat ambil dari modul untuk EEPROM jenis AT93C46/56/66 ini adalah list program yang dioperasikan untuk satu jenis saja seperti contoh untuk AT93C46 bisa dipisah menjadi 2 karena masing-masing untuk operasi dengan format data 8 bit dan satunya lagi untuk 16 bit. Belum lagi untuk AT93C56/66 juga sama berbeda antara format 8 dan 16 bit. Jadi kalau ingin maka program bisa sobat pisahkan menjadi 4 macam.



Udah ya, makasih udah baca postingan aku. Semoga bisa bermanfaat, sukur-sukur bisa diterapkan oleh sobat semua. Selamat mencoba ....

Salam....