Pendahuluan
Penempatan atau penyimpanan data dalam mikrokontroler AVR dapat dilakukan pada tiga macam memori yaitu memori flash, SRAM, dan EEPROM (Electrically Erasable Programmable Read Only Memory). EEPROM adalah salah satu memori untuk penyimpanan data internal mikrokontroler yang sifatnya non-volatile. Artinya data tidak akan hilang walaupun catu daya mikrokontroler mati. Biasanya memori EEPROM diaplikasikan misalnya untuk penyimpanan tabel-tabel data, atau konstanta, penyimpanan password, dan sebagainya. Setiap anggota keluarga mikrokontroler AVR mempunyai sejumlah EEPROM internal (on-chip).

ATmega16/8535 mempunyai memori EEPROM 512 byte sedangkan ATmega 32 1024 byte. EEPROM ini disusun sebagai ruang data yang terpisah dengan yang lain, dalam hal ini byte tunggal dapat dibaca dan ditulis. EEPROM memiliki ketahanan sedikitnya 100.000 siklus tulis/hapus. EEPROM diakses melalui register-register akses EEPROM, yaitu:
- EEPROM Address Register (EEAR)
- EEPROM Data Register (EEDR)
- EEPROM Control Register (EECR)
Register-Register EEPROM
Register Alamat EEPROM EEAR (EEPROM Address Register)
EEAR digunakan untuk menge-set alamat EEPROM (ke mana data akan ditulisi atau dari mana data akan dibaca). EEAR sebenarnya ada dua register yaitu EEARL dan EEARH.

- Bit 15..10 --> adalah bit-bit cadangan pada ATmega16 dan akan selalu dibaca sebagai low.
- Bit 9..0 - EEAR9..EEAR0 --> Alamat EEPROM. EEARH dan EEARL ditetapkan sebagai alamat EEPROM dalam ruang alamat sebesar 1024 byte. Byte data yang terdapat di dalam EEPROM ini dialamati secara linier antara 0 dan 1023.
.
Register Data EEPROM EEDR (EEPROM Data Register)
EEDR terdiri dari data yang akan ditulis/dibaca pada alamat yang ditunjuk oleh EEAR.

.
Register Kontrol EEPROM EECR (EEPROM Control Register)
EECR mempunyai bit-bit kontrol yang diperlukan untuk pembacaan dan penulisan EEPROM. Penulisan ke suatu EEPROM tidak sesederhana seperti menulis ke SRAM misalnya. Waktu akses tulis untuk EEPROM pada mikrokontroler AVR berkisar 2.5 sampai 4.0 ms, tergantung pada tegangan suplai.

- Bit 7...4 --> adalah bit-bit cadangan pada ATmega16 dan akan selalu dibaca sebagai low.
- Bit 3 - EERIE-EEPROM Ready Interrupt Enable. Dengan menuliskan high pada EERIE berarti mengaktifkan EEPROM Ready Interrupt dan jika bit I pada SREG juga di-set. Dengan menuliskan low pada EERIE berarti men-disable EEPROM Ready Interrupt. EEPROM Ready Interrupt membangkitkan interupsi terus menerus ketika EEWE clear.
- Bit 2 - EEMWE --> EEPROM Master Write Enable. Ketika EEMWE di-setting ke high maka EEPROM akan ditulisi.
- Bit 1 – EEWE --> EEPROM Write Enable. Bit ini merupakan bit strobe ke EEPROM. Ketika pengaturan alamat dan data benar, maka bit EEWE harus ditulisi satu untuk menulis nilai ke dalam EEPROM. Bit EEMWE harus ditulis satu sebelum logika satu ditulis ke EEWE, jika sebaliknya maka EEPROM tidak dapat ditulisi. Berikut adalah langkah - langkah yang harus diikuti ketika melakukan penulisan data EEPROM :
- Tunggu bit EEWE menjadi nol
- Tunggu bit SPMEN dalam SPMCR menjadi nol.
- Tulis alamat EEPROM ke EEAR (optional).
- Tulis data EEPROM ke EEDR (optional).
- Tulis logika satu pada bit EEMWE saat bit EEWE sudah menjadi nol Dalam empat siklus clock setelah mengatur bit EEMWE, tulis logika satu ke EEWE.
EEPROM tidak dapat diprogram selama CPU sedang melakukan penulisan ke memori Flash. Software harus memeriksa pemrograman memori flash telah selesai sebelum dimulai penulisan baru pada EEPROM. Langkah 2 hanya relavan jika software berisi Boot Loader yang diizinkan CPU untuk memprogram memori flash. Jika memori flash tidak di-update oleh CPU, maka langkah 2 tidak dapat diizinkan.
- Bit 0 – EERE --> EEPROM Read Enable. Bit ini berfungsi sebagai sinyal strobe baca pada EEPROM. Ketika alamat yang diberikan pada register EEAR telah benar, maka bit EERE harus ditulisi satu untuk memicu (trigger) pembacaan EEPROM. Ketika EEPROM dibaca, maka CPU berhenti selama empat siklus sebelum instruksi berikutnya dieksekusi. User harus melakukan polling pada bit EEWE sebelum memulai operasi baca. Jika sebuah operasi tulis sedang berlangsung, maka anda tidak dapat melakukan operasi baca EEPROM dan tidak dapat mengubah register EEAR. Berikut adalah langkah - langkah yang harus diikuti ketika melakukan pembacaan data EEPROM :
- Tunggu bit EEWE menjadi nol
- Tulis alamat EEPROM ke EEAR
- Set EERE = ‘1’ untuk mengaktifkan operasi baca pada alamat tertentu
- Baca register EEDR
Contoh 1:
Program berikut adalah bagaimana 8 saklar dibaca dari PORTC kemudian dikirimkan ke PORTA (LED) dan ditulis ke EEPROM dengan alamat 0x006C.

Program:

.
/*
* EEPROM INTERNAL 1.c
*
* Created: 03/02/2023 10:32:42
* Author : DELL
*/
#define F_CPU 8000000UL
#include<avr/io.h>
#include <util/delay.h>
int main (void)
{ //TOMBOL HARUS DITEKAN SAAT AWAL PROGRAM JALAN/SETELAH DI RESET
unsigned char saklar;
DDRA = 0xff; //PORTA sebagai output
DDRC = 0x00; //PORTC sebagai input
PORTC = 0xff; //pull-up resistor internal diaktifkan
saklar = PINC; //baca saklar
PORTA = saklar; //tampilkan pada PORTA (LED)
//=============
//tunggu sampai penulisan sebelumnya selesai
while (EECR & (1<<EEWE))
//===============
// Set up alamat dan register data
EEAR = 0x006C;
EEDR = saklar; //tulis karakter dari PINC ke dalam EEPROM alamat 0x006C
//===============
// tulis logika satu ke EEMWE
EECR |= (1<<EEMWE);
// --------------------------------------------- //
// Mulai menulis ke eeprom dengan men-setting EEWE
EECR |= (1<<EEWE);
//BUZZER
DDRB = 0x01;
PORTB = 0x01;
PORTB = 0x00;
_delay_ms(200);
PORTB = 0x01;
}
Video Demo:
.
.
Contoh 2:
Program berikut adalah bagaimana data yang tersimpan dalam EEPROM (dari push button yang ditekan pada PORTC) alamat 0x006C dibaca dan dikirim ke PORTA (LED).

Program:



.
/*
* EEPROM INTERNAL 2.c
*
* Created: 03/02/2023 10:42:37
* Author : DELL
*/
#define F_CPU 8000000UL
#include<avr/io.h>
#include <util/delay.h>
void tulisEEPROM(unsigned char dataEEPROM)
{
while (EECR & (1<<EEWE))
//===============
// Set up alamat dan register data
EEAR = 0x006C;
EEDR = dataEEPROM; //tulis karakter dari PINC ke dalam EEPROM alamat 0x006C
//===============
// tulis logika satu ke EEMWE
EECR |= (1<<EEMWE);
// --------------------------------------------- //
// Mulai menulis ke eeprom dengan men-setting EEWE
EECR |= (1<<EEWE);
//BUZZER
DDRB = 0x01;
PORTB = 0x01;
PORTB = 0x00;
_delay_ms(200);
PORTB = 0x01;
}
int main (void)
{
//MENULIS DATA PADA ALAMAT TERTENTU
DDRA = 0xff; //PORTA sebagai output
DDRC = 0x00; //PORTC sebagai input
PORTC = 0xff; //pull-up resistor internal diaktifkan
while(1)
{
switch (PINC){
case 0b11111110:
tulisEEPROM(0b11111110);
break;
case 0b11111101:
tulisEEPROM(0b11111101);
break;
case 0b11111011:
tulisEEPROM(0b11111011);
break;
case 0b11110111:
tulisEEPROM(0b11110111);
break;
case 0b11101111:
tulisEEPROM(0b11101111);
break;
case 0b11011111:
tulisEEPROM(0b11011111);
break;
case 0b10111111:
tulisEEPROM(0b10111111);
break;
case 0b01111111:
tulisEEPROM(0b01111111);
break;
}
//MEMBACA ISI EEPROM PADA ALAMAT 0x006C
while(EECR & (1<<EEWE)) //tunggu sampai penulisan sebelumnnya telah selesai
EEAR = 0x006C; //tulis alamat EEPROM yang dibaca
EECR |= (1<<EERE); //mulai baca eeprom dengan menulisi EERE
PORTA = EEDR; //ambil data pada reg. EEDR dan kirimkan ke PORTA
}
}
Video Demo:
.
.
Banyak laporan tentang korupsi data EEPROM, utamanya jika tegangan suplai sangat rendah. Menurut Atmel, solusi untuk mencegah korupsi data untuk on-chip EEPROM kurang lebih sama dengan pencegahan korupsi data untuk IC off-chip EEPROM. Secara spesifik korupsi data EEPROM dilaporkan terjadi pada alamat $00. Solusi-solusi yang direkomendasikan untuk pencegahan korupsi data EEPROM adalah sbb:
- Gunakan Brown-Out Detector (BOD) untuk memantau tegangan Vcc. Jika tegangan Vcc di bawah nilai trigger maka lakulan reset dan hindari menulis data pada EEPROM. Lebih baik me-reset sistem daripada terjadi korupsi data EEPROM.
- Jangan menggunakan semua memori EEPROM! Ini merupakan solusi yang agak esktrim. Namun demikian, terdapat korupsi data pada alamat $00, hal tersebut dapat berguna untuk menghindari penggunaan EEPROM alamat $00.
Mengakses EEPROM Dengan Library
Atmel studio bersama dengan compiler GCC menyediakan library ‘avr-libc’ bawaannya untuk pengaksesan EEPROM. Berikut ini header untuk pengaksesan library EEPROM:

Berikut ini adalah fungsi-fungsi yang berada di dalam file header EEPROM:

Fungsi-fungsi di atas digunakan untuk menulis/membaca EEPROM dan juga mendukung operasi data 8, 16, 32-bit dengan tipe data yang berbeda-beda.
Perbedaan antara fungsi write dan fungsi update
Perbedaan antara fungsi write dan fungsi update
Fungsi update dapat memeriksa apakah nilai data baru berbeda dengan nilai data lama yang berada pada alamat tertentu. Jika berbeda, maka data baru akan ditulis pada alamat tersebut. Cara ini akan menghemat waktu siklus penulisan data jika data baru = data lama dan juga memperpanjang masa penggunaan EEPROM.
Contoh:
Menulis dan membaca nilai byte: asumsikan kita akan menulis nilai = 55 pada alamat 64 EEPROM.

Baca nilai dari alamat 64 EEPROM, dalam nilai variabel uint8_t (hal yang sama (read/write nilai integer) dapat dilakukan, anda dapat menggunakan uint16_t.)

Menulis dan membaca nilai float: kita akan menulis nilai = 22.52 pada alamat 20 EEPROM, nilai float membutuhkan 4 byte.

Baca nilai float dari alamat 20 EEPROM.

.
Contoh 3:
Menulis dan membaca sekumpulan nilai: kita akan sekumpulan nilai dalam array = “GALINGGANG” pada alamat 0x0 EEPROM dan membacanya kembali dari EEPROM. Setelah dibaca, datanya ditampilkan pada LCD 16x2.
Program:

.
/*
* EEPROM INTERNAL 3.c
*
* Created: 03/02/2023 15:46:57
* Author : DELL
*/
#define F_CPU 8000000UL /* Define frequency here its 8MHz */
#include <avr/io.h> /* Include avr std header file */
#include <util/delay.h> /* Include delay header file */
#include <avr/eeprom.h> /* Include AVR EEPROM header file */
#include <string.h> /* Include string header file */
#include "LCD_16x2_H.h" /* Include LCD header file */
int main()
{
char R_array[15],W_array[15] = "GALINGGANG";
LCD_Init();/* Initialize LCD */
memset(R_array,0,15);
eeprom_busy_wait();
eeprom_write_block(W_array,0,strlen(W_array)); /* Write W_array
from EEPROM address 0 */
eeprom_read_block(R_array,0,strlen(W_array)); /* Read EEPROM
from address 0 */
LCD_String(R_array); /* Print Read_array on LCD */
return(0);
}
Video Demo:
.
Berikut ini link semua program di atas:
https://drive.google.com/file/d/1dGSQBxS50-_c_3DsU3ZCHdRjc89w3IRP/view?usp=sharing