PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anbindung externes SRAM an AtMega32



vklaffehn
29.04.2007, 14:32
Moin!
ich bin grade dabei, ein 32K SRAM an meinen AtMega32 zu basteln, die Schaltung ist folgendermaßen aufgebaut :

PORTA geht jeweils an die Eingänge von 2 74hc573n Latches und I0-I7 vom SRAM 62256, die Ausgänge der Latches sind an A0-A14 und CS vom SRAM, OE der Latches ist an GND, die LE Eingänge sind an PB0 (LE_low) und PB1 (LE_high), PB2 geht an WE und PB3 an OE.

Nun versuche ich, mit folgendem Code den RAM anzusprechen, aber ich kriege immer nur eine 0 gelesen, selbst wenn ich vorher versuche, etwas anderes zu schreiben.



void writemem(unsigned int addr, unsigned char value)
{
PORTB |= (WE);
PORTB |= (RE);

DDRA=0xff;

PORTA = (addr / 256);
PORTB |= (LE_low);
_delay_ms(10);
PORTB &= ~(LE_low);

PORTA = (addr & 255);
PORTB |= (LE_high);
_delay_ms(10);
PORTB &= ~(LE_high);

PORTA = value;
PORTB &= ~(WE);
_delay_ms(10);
PORTB |= (WE);
DDRA=0;
}

unsigned char readmem(unsigned int addr)
{
unsigned int value;

PORTB |= (WE);
PORTB |= (RE);

DDRA=0xff;

PORTA = (addr / 256);
PORTB |= (LE_low);
_delay_ms(10);
PORTB &= ~(LE_low);

PORTA = (addr & 255);
PORTB |= (LE_high);
_delay_ms(10);
PORTB &= ~(LE_high);

DDRA=0;
PORTA=0;
PORTB &= ~(RE);
_delay_ms(10);
value = PORTA;
PORTB |= (RE);
return value;
}


Als Test benutze ich dieses hier:


void memtest(void)
{
unsigned int addr;
unsigned char value;

for (addr=0;addr<32767;addr++)
{
writemem(addr,42);
value=readmem(addr);
uart_putc(value);

}
}


Was mache ich falsch?
Vielen Dank schonmal!!

vklaffehn
29.04.2007, 15:36
ok, vergesst das erstmal.... Wenn man Bits setzen will, sollte man auch einzelne Bits maskieren ....:-)
Bin wohl nicht ganz wach.

vklaffehn
29.04.2007, 16:15
Tja, leider geht's immer noch nicht, sieht jetzt folgendermaßen aus :


void initinterface(void)

{
DDRA=0;
DDRB |= 15;
PORTB |= (1<<WE);
PORTB |= (1<<RE);
PORTB &= ~(1<<LE_high);
PORTB &= ~(1<<LE_low);
}

void writemem(unsigned int addr, unsigned char value)
{
PORTB |= (1<<WE);
PORTB |= (1<<RE);

DDRA=0xff;

PORTA = (addr / 256);
PORTB |= (1<<LE_low);
_delay_ms(ws);
PORTB &= ~(1<<LE_low);

PORTA = (addr & 255);
PORTB |= (1<<LE_high);
_delay_ms(ws);
PORTB &= ~(1<<LE_high);

PORTA = value;
PORTB &= ~(1<<WE);
_delay_ms(ws);
PORTB |= (1<<WE);
DDRA=0;
}

unsigned char readmem(unsigned int addr)
{
unsigned int value;

PORTB |= (1<<WE);
PORTB |= (1<<RE);

DDRA=0xff;

PORTA = (addr / 256);
PORTB |= (1<<LE_low);
_delay_ms(ws);
PORTB &= ~(1<<LE_low);

PORTA = (addr & 255);
PORTB |= (1<<LE_high);
_delay_ms(ws);
PORTB &= ~(1<<LE_high);

DDRA=0;
PORTA=0;
PORTB &= ~(1<<RE);
_delay_ms(ws);
value = PORTA;
PORTB |= (1<<RE);
return value;
}

sowie

void memtest(void)
{
unsigned int addr;
unsigned char value;
initinterface();

for (addr=0;addr<32767;addr++)
{
writemem(addr,42);
value=readmem(addr);
uart_putc(value);

}
}


Irgendwie steh ich aufm Schlauch.....

vklaffehn
30.04.2007, 18:47
Argl...
einen Masseschluß und einem Tausch von Low- und Highbyte der Adresse später....


void initinterface(void)

{
DDRA=0;
PORTA=0;
DDRB |= 15;
PORTB |= (1<<WE);
PORTB |= (1<<OE);
PORTB &= ~(1<<LE_low);
PORTB &= ~(1<<LE_high);
}

void writemem(unsigned int addr, unsigned char value)
{
PORTB |= (1<<WE); //WE auf high
PORTB |= (1<<OE); //OE auf high

DDRA=0xff; //PORTA als Ausgang

PORTA = (addr / 256); //Highbyte der Adresse ausgeben
_delay_ms(ws);
PORTB |= (1<<LE_high); //Latch 1 input enable
_delay_ms(ws);
PORTB &= ~(1<<LE_high); //Latch 1 input disable
_delay_ms(ws);
PORTA = (addr & 255); //Lowbyte der Adresse ausgeben
_delay_ms(ws);
PORTB |= (1<<LE_low); //Latch 2 input enable
_delay_ms(ws);
PORTB &= ~(1<<LE_low); //Latch 2 input disable
_delay_ms(ws);
PORTA = value; //Daten ausgeben
PORTB &= ~(1<<WE); //WE auf low
_delay_ms(ws);
PORTB |= (1<<WE); //WE auf high
_delay_ms(ws);
DDRA=0; //PORTA auf Eingang
PORTA=0; //keine Pullups
}

unsigned char readmem(unsigned int addr)
{
unsigned char value;

PORTB |= (1<<WE); //WE auf high
PORTB |= (1<<OE); //OE auf high

DDRA=0xff; //PORTA als Ausgang

PORTA = (addr / 256); //Highbyte der Adresse ausgeben
_delay_ms(ws);
PORTB |= (1<<LE_high); //Latch 1 input enable
_delay_ms(ws);
PORTB &= ~(1<<LE_high); //Latch 1 input disable
_delay_ms(ws);
PORTA = (addr & 255); //Lowbyte der Adresse ausgeben
_delay_ms(ws);
PORTB |= (1<<LE_low); //Latch 2 input enable
_delay_ms(ws);
PORTB &= ~(1<<LE_low); //Latch 2 input disable
DDRA=0; //PORTA als Eingang
PORTA=0; //keine Pullups
_delay_ms(ws);
PORTB &= ~(1<<OE); //OE auf low
_delay_ms(ws);
value = PORTA; //Daten lesen nach 'value'
_delay_ms(ws);
PORTB |= (1<<OE); //OE auf high
_delay_ms(ws);
return value;
}


Zum testen hab ich jetzt mal ein paar Pullups beim lesen angeschaltet, merkwürdigerweise krieg ich dann auch genau diese Bits als high gelesen, also scheint das RAM irgendwie nicht das zu tun, was es soll, die Adressen kommen aber sauber an, und die Steuersignale auch.....

HILFEE!!