Gast
#367192
Hi Leute,
Ich verwende einen ATmega128, der mit dem externen Speicherinterface
zwei SRAM-Bausteine a 512kB anspricht. Dazu verwende ich drei weitere
Port Pins als Adressleitungen und zwei Port Pins um die SRAM-Bausteine
mittels Chip Enable zu de- / aktivieren.
Um den Speicher zu testen, habe ich ein kleines Testprogramm
geschrieben, das unten dargestellt ist. Das ganze klappt auch wunderbar
und ist soweit alles in Ordnung, ich habe nun eine Frage zu der
Initialisierung des externen Speicherinterface.
Im speziellen habe habe ich ne Frage zu dieser Codezeile
<c>
void xram(void) _attribute_ ((naked)) _attribute_ ((section
(".init1")));
</c>
So wie ich es verstanden habe sorgt man somit dafür, dass das
Speicherinterface frühzeitig initialisiert wird. Somit wird dem
Compiler? oder Linker? mitgeteilt, das er den externen Speicher nutzen
kann.
Oder sehe ich das falsch?
Ich habe das ganze auch mal ohne diese vorzeitige Initialisierung
gemacht, sondern die Funktion void xram(void) ganz normal in der
main()aufgerufen. Das Ergebnis war, dass es auch so funktionierte.
Deshalb meine weitere Frage, wozu macht man es dann und was kann
passieren, wenn mann es nicht macht?
Mir geht es darum, den Hintergrund zu verstehen, da ich es für eine
Ausarbeitung gebrauche und den Quellcode begründen soll.
Vielleicht hat der werte Herr Jörg Wunsch Zeit und Möglichkeit mir
darauf zu antworten, da ich diesen Code bzw. diese Befehlszeile in
einen Beitrag von ihn gefunden habe.
Hier nun mein kleines nicht sehr anspruchvolles, aber funktionierendes
Testprogramm
<c>
#include"lcd_i2c.h"
#include"i2cmaster.h"
#include "define.h"
#include <avr/io.h>
#include <stdio.h>
#define OFFSET 0x1100
#define SET_SRAM1 {PORTF |= (1<<PF1); PORTF &= ~(1<<PF0);}
#define SET_SRAM2 {PORTF |= (1<<PF0); PORTF &= ~(1<<PF1);}
#define BANK_0 {PORTF &= ~(1<<PF4); PORTF &= ~(1<<PF3); PORTF &=
~(1<<PF2);}
#define BANK_1 {PORTF &= ~(1<<PF4); PORTF &= ~(1<<PF3); PORTF |=
(1<<PF2);}
#define BANK_2 {PORTF &= ~(1<<PF4); PORTF |= (1<<PF3); PORTF &=
~(1<<PF2);}
#define BANK_3 {PORTF &= ~(1<<PF4); PORTF |= (1<<PF3); PORTF |=
(1<<PF2);}
#define BANK_4 {PORTF |= (1<<PF4); PORTF &= ~(1<<PF3); PORTF &=
~(1<<PF2);}
#define BANK_5 {PORTF |= (1<<PF4); PORTF &= ~(1<<PF3); PORTF |=
(1<<PF2);}
#define BANK_6 {PORTF |= (1<<PF4); PORTF |= (1<<PF3); PORTF &=
~(1<<PF2);}
#define BANK_7 {PORTF |= (1<<PF4); PORTF |= (1<<PF3); PORTF |=
(1<<PF2);}
void xram(void) _attribute_ ((naked)) _attribute_ ((section
(".init1")));
void xram(void)
{
MCUCR |= (1<<SRE)|(1<<SRW10); // The SRE Bit will activate the
memory
interface of the ATmega128
// The SRW11 and SRW10 bits control
XMCRA |= (1<<SRW11); // the number of wait-states
XMCRB |= (1<<XMBK); // Enable the buskeeper, witch ensure a
definied logic level
// on the lines AD7:0, otherwise they will be
tri-stated
// Remember: if you disable the memory Interface,
don´t
forget
// to disable the buskeeper too.
}
//**********************************************************************
********************************************
//The function memwrite fills up a memorybank of the selected SRAM
//alternate with 0x55 and 0xaa
//**********************************************************************
********************************************
void memwrite(void)
{
unsigned char *pwrite = (unsigned char *) (OFFSET + 0); // Pointer to
a unsigned char with the adress 0x1100
unsigned int count = 0;
for(count=0; count<= (0xFFFF-OFFSET); count++) // until the end of
the
memory
{
if(count%2) // odd memorycells
pwrite[count]=0x55;
else // even memorycells
pwrite[count]=0xaa;
}
}
//**********************************************************************
********************************************
//The function memread checks a memorybank of the selected SRAM
//if the cells has alternate values of 0x55 and 0xaa
//**********************************************************************
********************************************
unsigned int memread(void)
{
unsigned char *pread = (unsigned char *) (OFFSET + 0); // Pointer to
a
unsigned char with the adress 0x1100
unsigned int count = 0;
unsigned char error = 0;
do
{
if(count%2) // odd memorycells
{
if(pread[count]!=0x55) // Memorycell dosen´t contain the desired
value
error = 1;
}
else // even memorycells
{
if(pread[count]!=0xaa) // Memorycell dosen´t contain the desired
value
error = 1;
}
count++;
}while((count<=(0xFFFF-OFFSET))&&(error == 0)); // Ends with error or
the last memorycell
if(error)
{
return(count); // Memorycell "count" has a wrong value
// 1 <= count <= 0xef00
}
else
{
return(0); // no problems at all
}
}
//**********************************************************************
********************************************
//The function memtest uses the functions memwrite and memread.
//If the cells has a wrong value, it returns the number of the cell
//If there is no problem it returns a Zero
//**********************************************************************
********************************************
unsigned int memtest(void)
{
unsigned int i = 0;
memwrite();
i = memread();
return(i);
}
//**********************************************************************
********************************************
//The function error_diplay only shows the memorycell with the wrong
value inside
//**********************************************************************
********************************************
void error_display(unsigned char SRAM, unsigned char BANK, unsigned int
MEMORYCELL)
{
lcdi2c_ausgabexy("SRAM -> Bank ",0,0);
lcdi2c_ausgabenummer(SRAM, 5, 0);
lcdi2c_ausgabenummer(BANK, 15, 0);
lcdi2c_ausgabexy("Fehler beim Auslesen",0,1);
lcdi2c_ausgabexy("Speicherzelle: ",0,2);
lcdi2c_ausgabenummer(MEMORYCELL, 20, 2);
}
int main(void)
{
UCHAR x = 0;
unsigned int MEMORYCELL = 0;
i2c_init(); // initialitze the I2C-Bus
x = lcdi2c_init(); // checks the display
PORTF |=
(0<<PF7)|(0<<PF6)|(0<<PF5)|(0<<PF4)|(0<<PF3)|(0<<PF2)|(1<<PF1)|(1<<PF0);
DDRF |=
(0<<PF7)|(0<<PF6)|(0<<PF5)|(1<<PF4)|(1<<PF3)|(1<<PF2)|(1<<PF1)|(1<<PF0);
// Belegung PORTF
//
// PF0: /CE SRAM 1
// PF1: /CE SRAM 2
// PF2: Adressleitung 16
// PF3: Adressleitung 17
// PF4: Adressleitung 18
// PF5: Frei
// PF6: Frei
// PF7: Frei
SET_SRAM1
BANK_0
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 1,0 , MEMORYCELL);
else
{
BANK_1
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 1,1 , MEMORYCELL);
else
{
BANK_2
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 1,2 , MEMORYCELL);
else
{
BANK_3
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 1,3 , MEMORYCELL);
else
{
BANK_4
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 1,4 , MEMORYCELL);
else
{
BANK_5
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 1,5 , MEMORYCELL);
else
{
BANK_6
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 1,6 , MEMORYCELL);
else
{
BANK_7
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 1,7 , MEMORYCELL);
else
{
SET_SRAM2
BANK_0
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 2,0 , MEMORYCELL);
else
{
BANK_1
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 2,1 , MEMORYCELL);
else
{
BANK_2
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 2,2 , MEMORYCELL);
else
{
BANK_3
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 2,3 , MEMORYCELL);
else
{
BANK_4
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 2,4 , MEMORYCELL);
else
{
BANK_5
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 2,5 , MEMORYCELL);
else
{
BANK_6
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 2,6 , MEMORYCELL);
else
{
BANK_7
MEMORYCELL = memtest();
if(MEMORYCELL)
error_display( 2,7 , MEMORYCELL);
else
{
lcdi2c_ausgabexy("Speicherzellen
OK!",0,0); //Output on display
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
while(1)
{
}
}
</c>