Translate

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....


2 komentar:

  1. Pak Tolong di tampilkan kode yang lengkap aja pak biar nggak mumet, maaf baru pemula

    BalasHapus
  2. Sip nanti akan saya lakukan sesuai permintaan sobat semua. Yaitu source code yang tidak terpenggal termasuk listing kompilasi LST dan hasilnya pada file HEX

    Tapi untuk file HEX didownload aja ya...

    BalasHapus