Translate

Komunikasi Nirkabel PING-PONG



Bagi sobat yang senang bermain jejaring sosial menggunakan BBM (blackberry messanger), pasti tidak asing dengan istilah “PING”. Jauh sebelum media tersebut merajalela, istilah “PING” sudah lama dikenal dalam dunia informatika yaitu sebuah perintah untuk mengetahui respon dari sebuah perangkat dalam sebuah jaringan berdasarkan alamat IP. Jika alamat perangkat yang di-PING merespon maka itu tanda bahwa jaringan, perangkat dan alamat terhubung.

Sementara bagi sobat yang gemar berolahraga mungkin juga pernah mendengar atau bahkan memainkan sebuah permainan ketangkasan bola yang bernama “PING-PONG” atau mungkin lebih dikenal dengan nama tenis meja. Cara bermainnya, kita cukup melakukan serve dengan memukul bola menggunakan badge ke arah meja lawan. Jika di seberang sana ada lawan kita maka bola tersebut akan dikembalikan ke arah kita, kalau tidak ada, bagaimana ya?

Nah, dari dua paragraf di atas, meski tidak mendekati relevansinya, penulis bermaksud menganalogikan perangkat yang akan dibahas kali ini. Intinya adalah adanya hubungan 2 arah yang bersifat timbal balik. Sama halnya dengan ketika kita melakukan sebuah wawancara di mana pertanyaan yang kita lontarkan akan dijawab oleh lawan bicara kita dan jawaban yang diberikan harus sesuai dan tidak boleh salah.

Perangkat yang akan kita buat sesuai tajuk “Komunikasi Nirkabel PING-PONG” terdiri dari 2 bagian yaitu Master dan Slave, atau boleh disebut Penanya dan Penjawab, atau jika ingin sedikit keren kita gunakan istilah DTE (data terminal equipment) dan DCE (data communication equipment). Apapun nama dan istilah yang digunakan yang terpenting untuk diketahui bahwa ada 2 perangkat di mana keduanya harus dapat saling berkomunikasi dengan salah satu sebagai penanya dan lainnya menjawab. Salah satu perangkat akan mengirim data “PING” dan lainnya harus menjawab “PONG”.

Agar supaya lebih jelas adanya, maka berikut akan digambarkan blok diagram dari hubungan kedua perangkat yang saling berkomunikasi secara nirkabel PING dan PONG.



DTE akan mengirim sandi berupa data “PING” kemudian menunggu jawaban dari DCE yang ada dan terhubung. Jika tidak ada jawaban dikarenakan tidak ada DCE yang terhubung maka DTE secara terus menerus akan melontarkan data sandi “PING” tanpa mengenal lelah ataupun bosan, karena itu memang tugasnya.

Dari sisi DCE adalah menunggu adanya panggilan data sandi “PING” dari DTE kemudian dengan serta merta akan menjawab sandi tersebut dengan jawaban “PONG”. Jika tidak ada yang menyapa dengan sandi “PING” maka DCE akan terus menunggu dan menunggu dengan sabar tanpa mengenal bosan karena itu memang tugasnya untuk senantiasa siap siaga.

Bagaimana cara DTE dan DCE berkomunikasi?

Saat ide perangkat ini muncul dalam benak penulis karena adanya permintaan dari seorang teman untuk diimplementasikan pada pintu gerbang kantornya maka media atau sarana komunikasi yang digunakan sesuai dengan kondisi lapangan, terlintas untuk menggunakan INFRA MERAH. Meski demikian pada kenyataannya jelas tidak menggunakan data sandi jawaban “PONG” atau “PANG, PENG dan PUNG”. Namun pada tulisan ini untuk sekedar penyederhanaan menggunakan sandi tersebut sesuai judul tulisan.

DTE :    “Ping”
           (DTE mulai melakukan panggilan dan untuk beberapa sesaat kemudian ia pun menunggu jawaban dari seberang sana. Ternyata hingga batas waktu yang ditentukan masih tak ada juga yang menjawab.)
           “Ping”
           (Kembali untuk kesekian kalinya DTE memanggil dan terus memanggil sampai ada yang menjawab panggilannya.)
DCE :    “Pong”
           (Akhirnya ada juga DCE yang melintas dan mendengar panggilan tersebut kemudian menjawab. DTE pun senang, wajahnya terlihat cerah dan ia pun menindak lanjuti jawaban tersebut lalu melanjutkan dengan mengajukan beberapa pertanyaan berikut yang harus dijawab dengan benar.)
DTE :    “Nama?”
DCE :    “Sigit”
DTE :    “Alamat?”
DCE :    “Depok”
           (Usai menerima semua jawaban yang diperlukan maka DTE pun memeriksa pada “buku” memorinya dan mendapati ternyata nama serta alamat tersebut memang tertera dalam daftar. Selanjutnya iapun mempersilahkan DCE melanjutkan perjalanan dengan tidak lupa mencatat pada jurnal untuk keperluan pelaporan tugasnya.)

Seperti itulah kembali penulis analogikan tentang implementasi dari konsep perangkat dengan pendekatan istilah PING-PONG. Implementasi perangkat dengan konsep seperti ini bisa sangat luas sesuai kebutuhan kita. Contoh implementasi lain yang pernah penulis buat dengan cara ini adalah pada sistem tambahan dari elevator di sebuah apartemen di wilayah Jakarta.

Sekarang akan kita lanjutkan dengan penjelasan yang lebih detil tentang perangkat tersebut. Kita mulai dengan pemilihan komponen pemancar dan penerima infra merah. Untuk komponen pemancar digunakan sebuah IRLED jenis TSAL6200. Untuk penerimanya menggunakan seri TSOP48xx dimana penulis memilih TSOP4836 dengan frekuensi 36 kHz. Sementara untuk menggerakkan TSAL6200 agar menghasilkan kedipan sesuai frekuensi pembawa sebesar 36 kHz digunakan komponen lain yaitu NE555, sebuah multivibrator astable.



Rangkaian di atas adalah sebuah pemancar-penerima infra merah (IR transceiver). Untuk logika sinyal pemancar pada pin 4 (RESET) dari NE555 dihubungkan ke port P31 dan logika penerima pada pin 1 (OUT) dari TSOP4836 dihubungkan ke port P30 dari sistem mikrokontroler di mana penulis menggunakan AT89C2051. Agar NE555 membangkitkan vibrasi dengan frekuensi 36 kHz maka kita memerlukan 4 komponen yaitu P1, R1, R2 dan C1 di mana masing-masing bernilai 1k, 1k5, 2k dan 10n serta sebuah dioda 1N4148. Secara teoritis rangkaian dapat membangkitkan getaran dengan pengaturan posisi trimpot berkisar antara 32 sampai 41 kHz. Sebagai referensi rumusan teoritisnya sebagai berikut:

T1 = 0,69 x (P1 + R1) x C1
T2 = 0,69 x R2 x C1
Fo = 1 / (T1 + T2)

Baik DTE maupun DCE, keduanya dibangun dengan mikrokontroler AT89C2051. Perbedaan dari keduanya adalah pada DTE dilengkapi dengan gerbang keluaran untuk tujuan implementasi. Sementara pada DCE hanyalah fitur pemancar dan penerima infra merah. Berikut adalah aplikasi yang dijalankan pada DTE.

$mod51
      ;Aplikasi PING-PONG pada DTE

BufSerial         data  8h
RegStack          data  10h

LED_Respon        bit   p3.7

Seperti biasa, sesuai standar, pada bagian awal berisi konfigurasi untuk register dan gerbang. Selanjutnya adalah menuliskan program inisialisasi agar mikrokontroler mengaktifkan perintah berkaitan dengan komunikasi serial. Kita akan menetapkan register TL dan TH dengan nilai #0E8H untuk kecepatan data atau baudrate sebesar 1200 bps.

org   0h

Inisialisasi:
      mov   sp, #RegStack-1
      mov   pcon, #0
      mov   scon, #50h
      mov   tmod, #20h
      mov   ie, #90h
      mov   tl1, #0e8h
      mov   th1, #0e8h
      setb  tr1
      ajmp  DTE_Mulai

Berikut adalah perintah yang berkenaan dengan interupsi serial di mana data yang masuk pada SBUF akan diperiksa dan disimpan. Sebagai protokol START maka aplikasi akan memeriksa isi register R0 harus kosong kemudian awal data yang masuk yaitu karakter “P”.

org   23h
      jnb   ri, $
      clr   ri
      mov   a, sbuf
      cjne  r0, #0, Simpan_Serial
      cjne  a, #'P', Keluar_Serial
      mov   r0, #BufSerial

      Simpan_Serial:
            mov   @r0, a
            inc   r0
            cjne  r0, #BufSerial+4, Keluar_Serial
            mov   dptr, #Pong
            mov   r0, #BufSerial
            mov   r7, #4

Setelah data serial yang masuk disimpan sejumlah 4 byte maka selanjutnya akan diperiksa. Isi buffer pada #BufSerial akan diperiksa sesuai dengan data pada alamat memori #Pong. Jika isi keduanya sama yaitu “PONG”, maka aplikasi akan mengaktifkan gerbang LED_Respon sebagai tanda terhubung.

            Periksa_Serial:
                  clr   a
                  movc  a, @a+dptr
                  inc   dptr
                  xrl   a, @r0
                  jnz   Reset_Serial
                  inc   r0
                  djnz  r7, Periksa_Serial
                  clr   LED_Respon

            Reset_Serial:
                  mov   r0, #0

            Keluar_Serial:
                  reti

Kirim_Serial:
      clr   ea
      mov   sbuf, a
      jnb   ti, $
      clr   ti
      setb  ea
      ret

Aplikasi DTE sesungguhnya dimulai di sini. Perintah yang dijalankan adalah mengirim karakter “PING” secara serial.

DTE_Mulai:
      setb  LED_Respon
      mov   r0, #0

Panggilan:
      mov   dptr, #Ping
      mov   r7, #4

      Panggil:
            clr   a
            movc  a, @a+dptr
            inc   dptr
            acall Kirim_Serial
            djnz  r7, Panggil
            mov   r6, #255
            mov   r5, #255
            mov   r4, #6

Setiap kali melakukan pengiriman “PING”, aplikasi melakukan penundaan untuk menunggu respon jawaban dari DCE selama kurang lebih 3 detik sesuai isi register-register R4, R5 dan R6.

      Tunggu_Jawab:
            acall Waktu_Tunda
            jnz   Tunggu_Jawab
            jnb   LED_Respon, DTE_Mulai
            ajmp  Panggilan

Ping: db 'PING'
Pong: db 'PONG'

Waktu_Tunda:
      djnz  r6, Keluar_Tunda
      mov   r6, #255
      djnz  r5, Keluar_Tunda
      mov   r5, #255

      Keluar_Tunda:
            mov   a, r4
            dec   a
            ret
end

Selanjutnya kita lihat aplikasi yang dijalankan pada perangkat DCE. Sekilas beberapa baris berikut sama persis dengan aplikasi DTE. Jika Sobat membaca dengan teliti akan ditemukan perbedaannya.

$mod51
      ;Aplikasi PING-PONG pada DCE

BufSerial   data  8h
RegStack    data  10h

LED_Respon        bit   p3.7

org   0h

Inisialisasi:
      mov   sp, #RegStack-1
      mov   pcon, #0
      mov   scon, #50h
      mov   tmod, #20h
      mov   ie, #90h
      mov   tl1, #0e8h
      mov   th1, #0e8h
      setb  tr1
      ajmp  DCE_Mulai

org   23h
      jnb   ri, $
      clr   ri
      mov   a, sbuf
      cjne  r0, #0, Simpan_Serial
      cjne  a, #'P', Keluar_Serial
      mov   r0, #BufSerial

      Simpan_Serial:
            mov   @r0, a
            inc   r0
            cjne  r0, #BufSerial+4, Keluar_Serial
            mov   dptr, #Ping
            mov   r0, #BufSerial
            mov   r7, #4

Pada aplikasi DCE maka isi register DPTR pada perintah di atas adalah alamat “#Ping”. Sehingga jika data yang diterima sama yaitu “PING” maka aplikasi akan mengaktifkan LED_Respon.

            Periksa_Serial:
                  clr   a
                  movc  a, @a+dptr
                  inc   dptr
                  xrl   a, @r0
                  jnz   Reset_Serial
                  inc   r0
                  djnz  r7, Periksa_Serial
                  clr   LED_Respon

            Reset_Serial:
                  mov   r0, #0

            Keluar_Serial:
                  reti

Kirim_Serial:
      clr   ea
      mov   sbuf, a
      jnb   ti, $
      clr   ti
      setb  ea
      ret

Sampai di sini, aplikasi pada DCE boleh dibilang hampir sama persis kecuali perubahan alamat pada register DPTR saja. Baris perintah berikutnya barulah terlihat sangat jelas perbedaannya di mana aplikasi DCE bersifat pasif alias menunggu hingga LED_Respon aktif rendah untuk kemudian menjawabnya.

DCE_Mulai:
      setb  LED_Respon
      mov   r0, #0
      jb    LED_Respon, $
      mov   dptr, #Pong
      mov   r7, #4

      Jawaban:
            clr   a
            movc  a, @a+dptr
            inc   dptr
            acall Kirim_Serial
            djnz  r7, Jawaban
            ajmp  DCE_Mulai

Ping: db 'PING'
Pong: db 'PONG'

end



Sudah ya, terima kasih sudah membaca artikel aku. Semoga bermanfaat dan bisa diterapkan oleh sobat semua.

Salam....

Antarmuka I2C Untuk Memori AT24C32/64



Pada artikel sebelumnya, penulis sudah pernah membahas mengenai memori AT24C512. Maka kali ini akan penulis bahas mengenai memori sejenis yang memiliki kapasitas lebih kecil yaitu AT24C32 dan AT24C64. Sebenarnya secara pemrograman, kedua IC memori ini hampir sama persis dengan AT24C512 hanya ada beberapa perbedaan terutama pada kapasitas; besarnya byte pada prosedur PageWrite yaitu hanya 32 saja; waktu proses penulisan tWC yang hanya 10/5 ms; dan tentunya pin alamatnya yaitu A2, A1 dan A0.

Ini adalah 2 dari produk memori keluaran dari Atmel yaitu AT24C32 yang memiliki kapasitas sebesar 32.768 bit atau 4.096 byte dalam setiap kemasannya dan AT24C64 dengan kapasitas 65.536 bit atau 8.192 byte. Memori yang dikemas cukup efisien dalam penggunaan pin dalam antarmuka dengan mikrokontroler. Dikenal dengan nama 2-wire Serial EEPROM menggunakan teknologi I2C.


Untuk antarmuka dengan mikrokontroler, AT24C32/64 memiliki 2 pin SCL (serial clock) dan SDA (serial data). Operasi antarmuka yang dijalankan menurut kaidah I2C. Memori ini juga memiliki pin untuk tujuan pengalamatan yaitu A2, A1 dan A0 sehingga memungkinkan untuk penggunaan secara paralel hingga 8 unit sekaligus. Kita dapat merakit secara paralel memori ini dengan antarmuka I2C untuk mendapatkan maksimal sebesar 32 kByte untuk AT24C32 dan 64 kByte untuk AT24C64. Memori ini juga dilengkapi dengan pengaman terjadi kesalahan prosedur yang dapat menghilangkan isinya yaitu memiliki pin WP (write protect) di mana jika pin ini dihubungkan ke catu (Vcc) maka operasi tulis akan diabaikan.

Secara internal memori AT24C32/64 memiliki alamat 1010H pada MSB yang harus ditambahkan pada saat melakukan operasi pengalamatan diikuti oleh alamat sesuai dengan pin A2, A1 dan A0. Format pengalamatan unit memori ini dapat dilihat di bawah ini.


AT24C32/64 memiliki prosedur yang dapat dijalankan untuk operasi baca maupun tulis. Pada operasi menulis sendiri disediakan 2 mode yaitu Byte Write atau penulisan isi memori per-byte dan Page Write yaitu penulisan memori secara perhalaman dengan jumlah data perhalaman adalah 32 byte. Pada penulisan WordAddress yang terdiri dari 2 byte maka pada AT24C64, bit yang bertanda (*) adalah diabaikan karena memori jenis ini hanya memiliki alamat memori dari 0000H sampai 1FFFH. Sementara untuk AT24C32, bit yang bertanda (#) juga diabaikan karena memori jenis ini hanya memiliki alamat memori dari 0000H sampai 0FFFH saja.


Untuk melakukan prosedur baca tulis pada memori AT24C32/64 maka diperlukan program seperti di bawah ini. Isi dari program sama persis dengan AT24C512 yang sudah dibahas pada artikel sebelumnya. Karena sebab tersebut maka penulis melakukan sedikit perubahan pada beberapa bagian yaitu angka 512 untuk AT24C512 diganti 32 untuk AT24C32 dan 64 untuk AT24C64 dan beberapa catatan tentang apa saja yang perlu diubah dari list program di bawah ini.

Kita mulai pembahasan dengan subrutin AT24C32_Write yang dijalankan untuk menulis dalam mode single byte maupun page write. Untuk itu ada beberapa register yang harus ditetapkan. Register B diperlukan untuk menentukan alamat unit, karena AT24C32/64 memiliki alamat unit 2 bit (A2, A1 dan A0) maka nilai B bisa berisi antara 00H sampai 07H. Register akumulator (ACC) digunakan untuk menentukan banyaknya byte yang akan ditulis. Register R0 digunakan untuk menunjukkan data yang akan disimpan. Dan register DPTR untuk menentukan alamat memori dari AT24C32/64.

AT24C32_Write:

;     Input : B    > Unit Address
;             ACC  > Length Data, max 32 byte
;             R0   > Buffer Data
;             DPTR > Memory Address

Catatan:

Untuk memori AT24C64 subrutin AT24C32_Write di atas bisa diganti dengan AT24C64_Write.

Rutin AT24C32_Write selanjutnya akan menjalankan program dengan menyimpan banyaknya data yang akan ditulis dari akumulator ke register R7. Kemudian register B akan dimanipulasi ke akumulator dengan menambahkan nibel MSB dari AT24C32/64 yaitu 1010H. Karena proses menulis maka bit 0 akan dinolkan. Proses selanjutnya adalah mengirim Device Address dan Word Address di mana panjang word address adalah 2 byte. Setiap pengiriman byte data maka nilai bit FACK akan senantiasa diperiksa untuk memeriksa kesalahan unit memori.

      push  07h
      push  06h
      push  05h
      mov   r7, a
      acall I2C_Start_Con
      mov   a, b
      orl   a, #10100000b
      acall Master_Tx
      jnb   FACK, EndC32Write
      mov   a, dph
      acall Master_Tx
      jnb   FACK, EndC32Write
      mov   a, dpl
      acall Master_Tx
      jnb   FACK, EndC32Write

Sekarang memori AT24C32/64 siap untuk menerima data yang berasal dari register R0. Banyaknya data yang ditulis ditentukan oleh nilai register R7. Pada setiap byte yang ditulis, unit memori membutuhkan waktu (tWR) untuk proses penyimpanan selama kurang lebih 5 ms. Setelah seluruh data selesai ditulis maka akan diakhiri dengan memanggil subrutin I2C_Stop_Con.

      PageWrite:
            mov   a, @r0
            inc   r0
            acall Master_Tx
            jnb   FACK, EndPageWrite
            acall AT24C32_WriteDelay
            djnz  r7, PageWrite

            EndC32Write:
                  acall I2C_Stop_Con
                  pop   05h
                  pop   06h
                  pop   07h
                  ret

Untuk memberikan waktu bagi AT24C32/64 memproses penyimpana data maka diperlukan penundaan tWR selama kurang lebih 5 ms dengan subrutin penunda AT24C32_WriteDelay berikut.

            AT24C32_WriteDelay:
                  mov   r6, #10    

                  WriteDelay:
                        mov   r5, #250
                        djnz  r5, $
                        djnz  r6, WriteDelay
                        ret

Catatan:

Untuk penggunaan catu daya bagi memori dengan tegangan 1,8 volt maka sesuai referensi dari datasheet maka waktu tWR setidaknya 10 ms. Untuk itu nilai register R6 harus 20.

Nah, selanjutnya kita akan membahas mengenai pembacaan isi memori AT24C32/64. Register yang digunakan masih sama hanya saja fungsi register R0 di sini digunakan untuk menyimpan data dari memori. Prosedur berikutnya masih sama dengan proses menulis untuk pengiriman Device Address dan 2 byte WordAddress.

AT24C32_Read:

;     Input : B    > Unit Address
;             ACC  > Length Data, max buffer size
;             DPTR > Memory Address
;     Output      : R0   < Buffer Data

      push  07h
      mov   r7, a
      acall I2C_Start_Con
      mov   a, b
      orl   a, #10100000b
      acall Master_Tx
      jnb   FACK, EndC32Read
      mov   a, dph
      acall Master_Tx
      jnb   FACK, EndC32Read
      mov   a, dpl
      acall Master_Tx
      jnb   FACK, EndC32Read

Untuk proses membaca, kita perlu mengirimkan kembali perintah I2C_Start_Con dilanjutkan dengan mengirin DeviceAddress. Pada prosedur pembacaan maka nilai bit FLB (flag last bit) digunakan untuk menentukan proses karena pada setelah pembacaan byte terakhir, tidak akan mengirimkan sinyak Acknowledge.

      acall I2C_Start_Con
      mov   a, b
      orl   a, #10100001b
      acall Master_Tx
      jnb   FACK, EndC32Read
      clr   FLB

      SequentialRead:
            djnz  r7, SeqRead
            setb  FLB

            SeqRead:
                  acall Master_Rx
                  mov   @r0, a
                  inc   r0
                  jb    FLB, EndC32Read
                  ajmp  SequentialRead

      EndC32Read:
            acall I2C_Stop_Con
            pop   07h
            ret

Berikut adalah subrutin yang digunakan untuk me-reset memori pada beberapa kondisi seperti setelah protokol interupsi, power loss atau reset sistem. Prosedur reset hanyalah memberikan pulsa clock SCL sebanyak 9 kali dengan kondisi SDA tinggi. Dalam beberapa penerapan, penulis jarang menggunakan subrutin ini tapi untuk mengikuti prosedur sebaiknya digunakan.

AT24C32_Reset:
      push  07h
      push  06h
      setb  SDA
      mov   r7, #9

      Reset512:
            clr   SCL
            mov   r6, #2
            djnz  r6, $
            setb  SCL
            mov   r6, #2
            djnz  r6, $
            djnz  r7, Reset32
            jb    SDA, End512Reset
;           setb  Fail

      End32Reset:
            pop   06h
            pop   07h
            ret

Program di atas penulis masukkan dalam file bernama AT24C32.TXT untuk modul subrutin AT24C32 dan AT24C64.TXT untuk AT24C64 dengan atau tanpa perubahan agar dapat digunakan pada aplikasi lainnya.

Agar Sobat tidak bingung, aku lampirkan list program untuk I2C.TXT yang sudah pernah kutulis pada artikel “Antarmuka Dengan Protokol I2C” sebelumnya dapat dilihat berikut ini:

I2C_Check_Con:
      jb    SCL, SlaveReady
      clr   FSRDY
      ret

      SlaveReady:
            setb  FSRDY
            ret

I2C_Start_Con:
      clr   SCL
      setb  SDA
      setb  SCL
      clr   SDA
      acall Delay5us
      ret

I2C_Stop_Con:
      clr   SCL
      CLR   SDA
      acall Delay3us
      setb  SCL
      setb  SDA
      nop

Delay5us:
      nop

Delay3us:
      ret

Master_Tx:

;     Input : ACC > Data

      push  07h
      push  acc
      mov   r7, #8

      TxD_High:
            clr   SCL
            rlc   a
            jnc   TxD_Low
            setb  SDA
            ajmp  TxD_Pulse

      TxD_Low:
            clr   SDA

            TxD_Pulse:
                  setb  SCL
                  acall Delay3us
                  djnz  r7, TxD_High
                  clr   SCL
                  setb  SDA
                  acall Delay3us
                  setb  SCL
                  jnb   SDA, TxD_Ack
                  clr   FACK
                  ajmp  MTx_End

            TxD_Ack:
                  setb  FACK

      MTx_End:
            pop   acc
            pop   07h
            ret

Master_Rx:

;     Input  : FLB > 1/0     
;     Output : ACC < Data

      push  07h
      mov   r7, #8
      clr   c

      Next_RxD:
            clr   SCL
            setb  SDA
            acall Delay3us
            setb  SCL
            jnb   SDA, Rxd_Low
            setb  c
            ajmp  Save_RxD
      RxD_Low:
            clr   c

            Save_RxD:
                  rlc   a
                  djnz  r7, Next_Rxd
                  clr   SCL
                  jb    FLB, No_Ack
                  clr   SDA
                  ajmp  Ack_Pulse

            No_Ack:
                  setb  SDA

      Ack_Pulse:
            setb  SCL
            pop   07h
            ret



Sudah ya, terima kasih sudah membaca artikel ini. Semoga apa yang penulis sampaikan bermanfaat dan bisa diterapkan oleh sobat semua.

Salam....


Antarmuka I2C Untuk Memori AT24C512



Ini adalah salah satu produk memori keluaran dari Atmel yang memiliki kapasitas sebesar 524.288 bit atau 65.536 byte dalam setiap kemasannya. Memori yang dikemas cukup efisien dalam penggunaan pin dalam antarmuka dengan mikrokontroler. Dikenal dengan nama 2-wire Serial EEPROM menggunakan teknologi I2C.

  
Untuk antarmuka dengan mikrokontroler, AT24C512 memiliki 2 pin SCL (serial clock) dan SDA (serial data). Operasi antarmuka yang dijalankan menurut kaidah I2C. Memori ini juga memiliki pin untuk tujuan pengalamatan yaitu A1 dan A0 sehingga memungkinkan untuk penggunaan secara paralel hingga 4 unit sekaligus. Kita dapat merakit secara paralel memori ini dengan antarmuka I2C untuk mendapatkan maksimal sebesar 256 kByte. Memori ini juga dilengkapi dengan pengaman terjadi kesalahan prosedur yang dapat menghilangkan isinya yaitu memiliki pin WP (write protect) di mana jika pin ini dihubungkan ke catu (Vcc) maka operasi tulis akan diabaikan.

Secara internal memori AT24C512 memiliki alamat 1010H pada MSB yang harus ditambahkan pada saat melakukan operasi pengalamatan diikuti oleh alamat sesuai dengan pin A1 dan A0. Format pengalamatan unit memori ini dapat dilihat di bawah ini.


AT24C512 memiliki prosedur yang dapat dijalankan untuk operasi baca maupun tulis. Pada operasi menulis sendiri disediakan 2 mode yaitu Byte Write atau penulisan isi memori per-byte dan Page Write yaitu penulisan memori secara perhalaman dengan jumlah data perhalaman adalah 128 byte.

Catatan:

Jika Sobat menggunakan mikrokontroler Seri AT89, sepertinya untuk panjang data sebanyak 128 tidaklah mungkin. Untuk itu perlu sedikit modifikasi aplikasi. Mengenai hal ini mungkin akan kita bahas pada pembuatan sistem pengisi memori seri AT24C yang akan datang.


Untuk melakukan prosedur baca tulis pada memori AT24C512 maka diperlukan program seperti di bawah ini. Kita mulai pembahasan dengan subrutin AT24C512_Write yang dijalankan untuk menulis dalam mode single byte maupun page write. Untuk itu ada beberapa register yang harus ditetapkan. Register B diperlukan untuk menentukan alamat unit, karena AT24C512 memiliki alamat unit 2 bit (A1 dan A0) maka nilai B bisa berisi antara 00H sampai 03H. Register akumulator (ACC) digunakan untuk menentukan banyaknya byte yang akan ditulis. Register R0 digunakan untuk menunjukkan data yang akan disimpan. Dan register DPTR untuk menentukan alamat memori dari AT24C512.

AT24C512_Write:

;     Input : B    > Unit Address
;             ACC  > Length Data, max 128 byte
;             R0   > Buffer Data
;             DPTR > Memory Address

Rutin AT24C512_Write selanjutnya akan menjalankan program dengan menyimpan banyaknya data yang akan ditulis dari akumulator ke register R7. Kemudian register B akan dimanipulasi ke akumulator dengan menambahkan nibel MSB dari AT24C512 yaitu 1010H. Karena proses menulis maka bit 0 akan dinolkan. Proses selanjutnya adalah mengirim Device Address dan Word Address di mana panjang word address adalah 2 byte. Setiap pengiriman byte data maka nilai bit FACK akan senantiasa diperiksa untuk memeriksa kesalahan unit memori.

      push  07h
      push  06h
      push  05h
      mov   r7, a
      acall I2C_Start_Con
      mov   a, b
      orl   a, #10100000b
      acall Master_Tx
      jnb   FACK, EndC512Write
      mov   a, dph
      acall Master_Tx
      jnb   FACK, EndC512Write
      mov   a, dpl
      acall Master_Tx
      jnb   FACK, EndC512Write

Sekarang memori AT24C512 siap untuk menerima data yang berasal dari register R0. Banyaknya data yang ditulis ditentukan oleh nilai register R7. Pada setiap byte yang ditulis, unit memori membutuhkan waktu (tWR) untuk proses penyimpanan selama kurang lebih 10 ms. Setelah seluruh data selesai ditulis maka akan diakhiri dengan memanggil subrutin I2C_Stop_Con.

      PageWrite:
            mov   a, @r0
            inc   r0
            acall Master_Tx
            jnb   FACK, EndPageWrite
            acall AT24C512_WriteDelay
            djnz  r7, PageWrite

            EndC512Write:
                  acall I2C_Stop_Con
                  pop   05h
                  pop   06h
                  pop   07h
                  ret

Untuk memberikan waktu bagi AT24C512 memproses penyimpana data maka diperlukan penundaan tWR selama kurang lebih 10 ms dengan subrutin penunda AT24C512_WriteDelay berikut.

            AT24C512_WriteDelay:
                  mov   r6, #20    

                  WriteDelay:
                        mov   r5, #250
                        djnz  r5, $
                        djnz  r6, WriteDelay
                        ret

Catatan:

Untuk penggunaan catu daya bagi memori dengan tegangan 1,8 volt maka sesuai referensi dari datasheet maka waktu tWR setidaknya 20 ms. Untuk itu nilai register R6 harus 40.

Nah, selanjutnya kita akan membahas mengenai pembacaan isi memori AT24C512. Register yang digunakan masih sama hanya saja fungsi register R0 di sini digunakan untuk menyimpan data dari memori. Prosedur berikutnya masih sama dengan proses menulis untuk pengiriman Device Address dan 2 byte WordAddress.

AT24C512_Read:

;     Input : B    > Unit Address
;             ACC  > Length Data, max buffer size
;             DPTR > Memory Address
;     Output      : R0   < Buffer Data

      push  07h
      mov   r7, a
      acall I2C_Start_Con
      mov   a, b
      orl   a, #10100000b
      acall Master_Tx
      jnb   FACK, EndC512Read
      mov   a, dph
      acall Master_Tx
      jnb   FACK, EndC512Read
      mov   a, dpl
      acall Master_Tx
      jnb   FACK, EndC512Read

Untuk proses membaca, kita perlu mengirimkan kembali perintah I2C_Start_Con dilanjutkan dengan mengirin DeviceAddress. Pada prosedur pembacaan maka nilai bit FLB (flag last bit) digunakan untuk menentukan proses karena pada setelah pembacaan byte terakhir, tidak akan mengirimkan sinyak Acknowledge.

      acall I2C_Start_Con
      mov   a, b
      orl   a, #10100001b
      acall Master_Tx
      jnb   FACK, EndC512Read
      clr   FLB

      SequentialRead:
            djnz  r7, SeqRead
            setb  FLB

            SeqRead:
                  acall Master_Rx
                  mov   @r0, a
                  inc   r0
                  jb    FLB, EndC512Read
                  ajmp  SequentialRead

      EndC512Read:
            acall I2C_Stop_Con
            pop   07h
            ret

Berikut adalah subrutin yang digunakan untuk me-reset memori pada beberapa kondisi seperti setelah protokol interupsi, power loss atau reset sistem. Prosedur reset hanyalah memberikan pulsa clock SCL sebanyak 9 kali dengan kondisi SDA tinggi. Dalam beberapa penerapan, penulis jarang menggunakan subrutin ini tapi untuk mengikuti prosedur sebaiknya digunakan.

AT24C512_Reset:
      push  07h
      push  06h
      setb  SDA
      mov   r7, #9

      Reset512:
            clr   SCL
            mov   r6, #2
            djnz  r6, $
            setb  SCL
            mov   r6, #2
            djnz  r6, $
            djnz  r7, Reset512
            jb    SDA, End512Reset
;           setb  Fail

      End512Reset:
            pop   06h
            pop   07h
            ret

Program di atas penulis masukkan dalam file bernama AT24C512.TXT untuk menjadi modul pada aplikasi lainnya.

Agar Sobat tidak bingung, aku lampirkan list program untuk I2C.TXT yang sudah pernah kutulis pada artikel “Antarmuka Dengan Protokol I2C” sebelumnya dapat dilihat berikut ini:

I2C_Check_Con:
      jb    SCL, SlaveReady
      clr   FSRDY
      ret

      SlaveReady:
            setb  FSRDY
            ret

I2C_Start_Con:
      clr   SCL
      setb  SDA
      setb  SCL
      clr   SDA
      acall Delay5us
      ret

I2C_Stop_Con:
      clr   SCL
      CLR   SDA
      acall Delay3us
      setb  SCL
      setb  SDA
      nop

Delay5us:
      nop

Delay3us:
      ret

Master_Tx:

;     Input : ACC > Data

      push  07h
      push  acc
      mov   r7, #8

      TxD_High:
            clr   SCL
            rlc   a
            jnc   TxD_Low
            setb  SDA
            ajmp  TxD_Pulse

      TxD_Low:
            clr   SDA

            TxD_Pulse:
                  setb  SCL
                  acall Delay3us
                  djnz  r7, TxD_High
                  clr   SCL
                  setb  SDA
                  acall Delay3us
                  setb  SCL
                  jnb   SDA, TxD_Ack
                  clr   FACK
                  ajmp  MTx_End

            TxD_Ack:
                  setb  FACK

      MTx_End:
            pop   acc
            pop   07h
            ret

Master_Rx:

;     Input  : FLB > 1/0     
;     Output : ACC < Data

      push  07h
      mov   r7, #8
      clr   c

      Next_RxD:
            clr   SCL
            setb  SDA
            acall Delay3us
            setb  SCL
            jnb   SDA, Rxd_Low
            setb  c
            ajmp  Save_RxD
      RxD_Low:
            clr   c

            Save_RxD:
                  rlc   a
                  djnz  r7, Next_Rxd
                  clr   SCL
                  jb    FLB, No_Ack
                  clr   SDA
                  ajmp  Ack_Pulse

            No_Ack:
                  setb  SDA

      Ack_Pulse:
            setb  SCL
            pop   07h
            ret



Sudah ya, terima kasih sudah membaca artikel ini. Semoga apa yang penulis sampaikan bermanfaat dan bisa diterapkan oleh sobat semua.

Salam....