ATmega128 i zewnętrzna pamięć

Cześć!

W programie zabrakło mi SRAM'u, toteż musiałem dołożyć atmedze pamięci. Użyłem układu U6264DC z latchem 74HC573. Pamięć wydaje się działać, jednak mam z nią dziwny problem.

Napisałem sobie w C program sprawdzający pamięć.

Najpierw alokuję dużą tablicę, potem piszę do niej określone wartości, a nastepnie sprawdzam czy są ok. Jeśli nie to wyrzucam na wyświetlacz numer "komorki" tablicy i jej zawartość (funkcją debug(...)).

Kod wygląda mniej-więcej tak:

#v+ #define TAB_LENGTH 0x7FFF #define TEST_VAL 0xAA

u8 tab[TAB_LENGTH];

int main() { u16 i; debug_init(); avr_memory_init(); for (i = 0; i < TAB_LENGTH; i++) { tab[i] = TEST_VAL; } for (i = 0; i < TAB_LENGTH; i++) { debug(1, (i >> 8) & 0xFF, i & 0xFF); if (tab[i] != TEST_VAL) { delay_ms(500); debug(1, (tab[i] >> 8) & 0xFF, tab[i] & 0xFF); delay_ms(2000); } } } #v-

Problemy są takie:

  1. Jeśli próbuję zaalokować tablicę większą niż 0x7FFF kompilator wyrzuca błąd: $ make all avr-gcc -g -mmcu=atmega128 -Wall -Os -o main.elf main.c delay.o debug.o avr_memory.o main.c:13: error: size of array `tab' is too large main.c:13: error: storage size of `tab' isn't known Pytanie... dlaczego? Przecież m128 adresuje do 64k zewnętrzej pamięci (objętość = 64k * 8 [bajtów]).

  1. Dwanaście "komórek" tablicy podczas czytania ma inną wartość niż wcześniej została do nich zapisana. Co dziwniejsze, są to zawsze te same wartości! Komórki, które sprawiają kłopoty to 0x0FF4 - 0x0FFF.

komórka | wartość

0x0FF4 0x01 0x0FF5 0x2C 0x0FF6 0x0F 0x0FF7 0xF7 0x0FF8 0x0F 0x0FF9 0xF9 0x0FFA 0x00 0x0FFB 0xBB 0x0FFC 0x0F 0x0FFD 0xFD 0x0FFE 0x00 0x0FFF 0x9C

Uwaga: "komórki" to nie są adresy w pamięci tylko indeksy kolejnych danych w tablicy tab. Niestety, słabo posługuję się asemblerem, więc patrzenie w kod asm niewiele mi pomogło. Ale wyrzuciłem go tu:

formatting link

- może zechcecie zerknąć? Może na jego podstawie ktoś życzliwie powie mi, dlaczego 12 komórek pamięci "nie działa"?

Zauważylem jeszcze coś. jak zmieniam wartość TEST_VAL, zmieniaja się również wartości komórek 0x0FF5, 0x0FFB i 0x0FFF. Reszta jest taka sama.

Pozdrawiam i czekam na rady, voice

Reply to
voice
Loading thread data ...

Czyli ta pamiec to 8kB

Czyli TAB_LENGTH to 32kB - to jest jeden błąd

formatting link

A jak myslisz gdzie jest stos umieszczony ? To jest drugi blad

MK

Reply to
MK

No tak, masz rację. Zasugerowałem się objętością pamięci... 8k x 8 = 64kB

- ale to przeciez nie jest ilosc adresów.

Zgadza sie. Dzięki! Zmieniłem TAB_LENGTH na 0x2000 ale w dalszym ciągu otrzymuję te same wyniki. to pewni wina drugiedo błędu...

W wewnętrznym SRAM'ie, o ile się orientuję. Niestety, jak pisałem, z asemblerem jestem trochę na bakier i może dlatego nie rozumiem pewnych rzeczy...

Napisz mi, proszę na czym polega drugi błąd, bo sam niestety nie mogę na to wpaść. W jaki sposób mogę go rozwiązać?

Pozdrawiam, voice

Reply to
voice

Tue, 15 Jun 2004 00:57:14 +0200, na pl.misc.elektronika, voice napisał(a):

Tak on ma - tablice są ograniczone. Używaj wskaźnika do zapisu pod kolejne adresy.

Nie sprawdzaj od zera, bo włazisz na wewnętrzną pamięć kostki - zaczynaj od pierwszego adresu zewnętrznego ( = rozmiar wewnętrznej pamięci ).

Reply to
Jurek Szczesiul

Ale dlaczego? Czy po dołączeniu dodatkowego SRAM'u, nie zwiększa się po prostu przestrzeń pamięci na stos, stałe itd.?

To znaczy, mam rozumieć, że cała pamięć (wewnętrzna i zewnętrzna) nie jest "ciągła"? Czyli, jeśli zadeklaruję np. 2 tablice:

unsigned char tab1[0x0C00]; // 3/4 wewnętrznego SRAM'u (0x1000) unsigned char tab2[0x0C00];

to gdzieś w okolicy 1/4 drugiej tablicy pojawią mi się jakieś krzaki?

Jeśli tak, to co zrobić, żeby tego uniknąć?

Pozdrawiam, voice

Reply to
voice

Tue, 15 Jun 2004 12:02:10 +0200, na pl.misc.elektronika, voice napisał(a):

Zbyt ogólnikowo napisałem. Pamięć jest ciągła oczywiście. Ale gcc przy starcie ustawia wskaźnik stosu na koniec pamięci wewnętrznej (RAMEND ), natomiast obszar danych zaczyna się zaraz za rejestrami. Jeśli w takim ( domyślnym ) układzie zajmujesz dużo danych to wchodzisz na stos - kompilator przed tym nie ostrzega. Zazwyczaj przerzuca się sekcję danych na początek pamięci zewnętrznej, przesuwanie stosu jest raczej niewskazane ze względu na mniejszą szybkość dostępu. Zobacz najlepiej w manualu avr-libc - tam obszary i używanie pamięci są dokładnie rozrysowane.

Reply to
Jurek Szczesiul

Dziękuję za rozjaśneinie tematu! Manual jak zwykle okazał się nieocenioną kopalnią wiedzy :)

Zainicjowałem XMEM w sekcji .init1, a linkerowi powiedziałem, żeby wszucił sekcję .data właśnie do XMEM. Teraz wszystko działa jak trzeba (na razie).

Pozdrawiam i dziękuję za pomoc, voice

Reply to
voice

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.