- uint8_t eeprom_read_byte (const uint8_t *addr)
- void eeprom_write_byte (uint8_t *addr, uint8_t value)
- uint16_t eeprom_read_word (const uint16_t *addr)
- void eeprom_write_word (uint16_t *addr, uint16_t value)
- void eeprom_read_block (void *pointer_ram, const void *pointer_eeprom, size_t n)
- void eeprom_write_block (const void *pointer_ram, void *pointer_eeprom, size_t n)
Tampilkan postingan dengan label gcc. Tampilkan semua postingan
Tampilkan postingan dengan label gcc. Tampilkan semua postingan
Kamis, 20 Juni 2013
Tutorial: Menghemat memory Statis dengan PROGMEM dan EEPROM
Anda mungkin akan terkejut ketika melihat kenyataan terbatasnya jumlah memory yang disediakan oleh ic avr yang tersedia di pasaran. Bayangkan saja ATTINY2313 hanya memiliky 128 byte memory (lebar 8 bit) sedangkan ATMega8535 memiliki 512 byte saja. Setiap data variabel statis, semisal data text yang akan dikirim menuju lcd kadang menyebabkan memory RAM menjadi habis, padahal harus ada space RAM yang cukup untuk menampung data-data dinamis yg berubah sesuai jalannya program. Untuk itu data statis ini dapat disimpan ke dalam FLASH (PROGMEM) atau EEPROM.
PROGMEM
Progmem merupakan pemanfaatan memory flash / program sebagai penyimpan data statis. Pada mode scripting GCC inisialisasi awal yang harus di deklarasikan adalah #include <avr/pgmspace.h>. Pemanfaatan progmem cukup membantu menghemat RAM akan tetapi sebelum menuangkannnya ke dalam perhitungan atau penulisan ke lcd / UART, isi dari memory flash perlu dipindahkan ke memory RAM. Perhatikan contoh berikut ini.
contoh 1
char angka = 30;
char angka2;
Variable angka diatas berada di RAM, jika ingin memanfaatkan variabel diatas cukup gampang.
angka2 = angka * 2;
Jika variabel angka dirubah dirubah berada di FLASH , maka perubahannya seperti berikut:
contoh 2
const char angka PROGMEM= 30;
char angka2,angka3;
untuk mendapatkan hasil perhitungan yang sama maka harus ada variabel angka3 yang akan memindahkan data dari variabel angka (yang berada di flash) menuju RAM.
angka3 = pgm_read_byte(&angka); //yg dimaksud &angka adalah alamat memory
angka2= angka3 * 2;
Tentunya contoh diatas tidak menggambarkan penghematan memory, tapi perhatikanlah contoh penulisan variabel array tulisan yang panjang ke UART berikut ini:
const char tulisan[] PROGMEM= "ahocool hebat sekali lo broo";
void USART_Tx(unsigned char data)
{
while (!(UCSRA & (1<<UDRE)));{}
UDR = data;
}
void kirim_text(const char *data)
{
while (pgm_read_byte(data) != 0x00)
USART_Tx(pgm_read_byte(data++));
}
Dari fungsi diatas , routine kirim_text akan mengirimkan isi dari memory flash satu persatu ke UART, sehingga tidak perlu memindahkan semua data tulisan ke RAM cukup hanya dipindahkan secara berurutan. Perintah untuk mengirim text ascii ke UART seperti berikut ini :
kirim_text(tulisan);
Apabila pembaca sering memperhatikan script yang ditulis diblog ini, terutama yang berhubungan dengan LCD maka penulisan teks variable tulisan seperti contoh diatas, cukup menuliskan seperti ini:
lcd_puts_P(tulisan)
untuk lebih lengkapnya dapat membaca penjelasan mengenai library pgmspace.h disini
EEPROM
Salah satu keunggulan dari microcontroller AVR adalah adanya memory non volatile (tidak akan hilang saat tidak ada power) yang berupa EEPROM. Biasanya penggunaanya adalah sebagai penyimpan data statis seperti halnya PROGMEM dan yang paling penting adalah variabel dinamis yang akan berubah nilainya dan kemudian nilainya akan disimpan seterusnya walau saat microcontroller dimatikan. Inisialisasi librarynya dilakukan dengan menuliskan #include <avr/eeprom.h>.
Beberapa perintah script EEPROM yang paling penting adalah :
Contoh paling sederhana adalah pembacaan dan penyimpanan data kalibrasi seperti contoh berikut:
uint8_t EEMEM kalibrasi=100;
char berubah;
untuk membaca nilai EEPROM dan memindahkan ke RAM seperti ini :
berubah=eeprom_read_byte(&kalibrasi);
semisal nilai variabel "berubah" memang berubah karena perjalanan dari aplikasi, maka ketika ingin menyimpannya ke EEPROM tuliskan script seperti berikut:
eeprom_write_byte(&kalibrasi,berubah);
cukup mudah bukan? Bagaimana jika ingin menuliskan data EEPROM ke LCD atau UART ? contohnya seperti berikut ini :
uint8_t EEMEM edit_tgl[]= " *EDIT KALENDER*$";
void tulis_ee(uint8_t *eem)
{
uint8_t a=0;
while(eeprom_read_byte(eem + a) != '$')
{
lcd_putc(eeprom_read_byte(eem + a));
a++;
}
}
contoh diatas sering digunakan oleh penulis untuk menyimpan data-data teks yg akan ditulis ke LCD, dengan sebuah trick menempatkan tanda $ sebagai penanda akhir kalimat (tentunya karakter lain bisa saja, asal karakternya jarang digunakan). untuk menulis ke LCD cukup menuliskan script berikut:
tulis_ee(edit_tgl);
Bagaimana dengan mengirim UART ? Perhatikan contoh berikut:
uint8_t EEMEM tulisan[]= "ahocool memang ganteng banget broo !!";
void USART_Tx(unsigned char data)
{
while (!(UCSRA & (1<<UDRE)));{}
UDR = data;
}
void kirim_text_ee(const char *data)
{
while (eeprom_read_byte(data) != 0x00)
USART_Tx(eeprom_read_byte(data++));
}
Dan selanjutnya sangat mudah hanya cukup menuliskan :
kirim_text_ee(tulisan);
SELAMAT MENCOBA