Matt Kucia

Cloud, software, hardware


/projects/avrc/art/0x08

PROGMEM

Przeanalizujmy następujący fragment kodu:

LCD_write("Jakis tekst");

Jest to fragment kodu wypisujący na wyświetlaczu LCD tekst. Pomimo że wydaje się to optymalnym rozwiązaniem takim nie jest. Co się powinno dziać w przypadku wywołania takiej funkcji? Funkcja powinna pobierać znak po znaku każdą literę z pamięci programu i wysyłać je do wyświetlacza. Niestety funkcja ta nie odczytuje tekstu z pamięci programu (przypominam FLASH) lecz z pamięci RAM co jest wielką stratą i kosztuje nas cykle pracy układu. Jest jednak sposób na oszczędzenie pamięci.

Będziemy korzystać z nagłówka: #include <avr/pgmspace.h> Teraz jeżeli chcemy przechowywać łańcuch znaków tylko w pamięci programu napiszemy:

const char string[] PROGMEM = "Ten łańcuch znaków nie może zostać zmieniony i jest przechowywany w pamięci FLASH.";

Lub kożystając z makra możemy wprowadzać łańcuchy wewnątrz kodu:

LCD_write_P(PSTR("Program Memory String"));

Niestety to nie wszystko co trzeba zrobić, zmienna ''string'' oraz makro zwracają adres w pamięci FLASH a nie RAM tak jak jest to oczekiwane przez dotychczas istniejące funkcje. Trzeba je niestety zmodyfikować. Przeanalizujmy następujące fragmenty kodu:

while (*data != '\0') ...
while (pgm_read_byte(data) != 0x00)

W przypadku odczytu z pamięci RAM korzystamy z pierwszej pętli natomiast aby odczytać bajt z pamięci programu należy wykorzystać funkcję ''pgm_read_byte''. Często wyróżnia się funkcje odczytujące z pamięci FLASH kończąc ich nazwę na ''_P''.

Bardzo dobre opracowanie PROGMEM: AVRFreaks [EN]