logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C] Jak obsługiwać pamięci równoległe PEROM np.AT29C020

narasta 15 Cze 2009 20:50 1328 2
REKLAMA
  • #1 6660500
    narasta
    Poziom 21  
    Dziś przypadkowo znalazłem w szufladzie pamięć AT29C020 (2Mb = 8x256k). Przy okazji nauki obsługi kolorowego wyświetlacza LCD pomyślałem, że ta pamięć nada się idealnie. Przyszedł więc czas na napisanie protokołu komunikacji z pamięcią. Otwarłem więc notę katalogową i na jej podstawie postanowiłem napisać program do obsługi (w C).

    Harware:
    ATMEGA32 + AT29C020
    PORTA jako linia adresowa (na razie tylko 8 bitów bo zabrakło mi już kabelków do łączenia na płytce testowej) PORTA.0-7 -> A.0-7, A.8-17 pływajace
    PORTC jako linia danych (8 bitów do wysyłania i odbierania danych) PORTC.0-7 -> D.7-0 (odwrócone)
    PORTD2 = !CE
    PORTD3 = !OE
    PORTD4 = !WE

    Software:
    
    #include "func.h"
    #include "uart.h"
    #include <util/delay.h>
    
    #define adrDIR DDRA
    #define adrPORT PORTA
    
    #define dtaDIR DDRC
    #define dtaPORT PORTC
    #define dtaPIN PINC
    
    #define setPORT PORTD
    #define setDIR DDRD
    
    #define CE (1<<PD2)
    #define OE (1<<PD3)
    #define WE (1<<PD4)
    
    void InitMEM(void)
    {
    	adrDIR = 0xFF;			// addresing port as OUT
    	adrPORT = 0x00;			// set addres 0
    	
    	setDIR = 0xFF;		
    }
    
    int read_mem(int adrx)
    {
    	PrintString("\r\n\r\n");
    
    	dtaDIR = 0x00; 			// data IN
    	dtaPORT = 0xFF;			// pull up to +
    
    	_delay_us(500);
    
    	
    	int mem = 0;
    
    	int adr = 0;
    
    	int licznik = 0;
    
    	while(adr<0xFF)
    	{
    		adrPORT = adr;
    
    		setPORT &= ~CE; 
    		setPORT &= ~OE; 
    		setPORT &= ~WE; 
    
    		_delay_ms(4);
    
    		int q = 255 - dtaPIN;
    
    		adrPORT = 0x00;
    		setPORT |= CE; 
    		setPORT |= OE; 
    
    		if(q<10) PrintString(" ");
    		if(q<100) PrintString(" ");
    		PrintString(itoch(q));
    		PrintString(" ");
    		adr++;
    
    		licznik++;
    		if(licznik>10)
    		{
    			licznik = 0;
    			PrintString("\r\n");
    		}
    	}
    
    	return mem;	
    }
    
    void write_mem(int adrx, int value)
    {
    	PrintString("\r\n\r\n");
    	dtaDIR = 0xFF; 			// data OUT
    	dtaPORT = 0x00;			// reset data port
    
    	int adr = 0;
    
    	int licznik = 0;
    
    	while(adr<0xFF)
    	{
    		setPORT |= OE;		//OE HIGH 
    		
    		adrPORT = adr;		//set addres
    		dtaPORT = value;	//data to write
    		_delay_us(100);
    
    		setPORT &= ~CE; 	//CE LOW
    		_delay_us(200);
    
    		setPORT &= ~WE;		//WE LOW
    		_delay_ms(4);		//wait for writing
    
    
    		setPORT |= WE;		//WE HIGH
    		setPORT &= ~OE;		//OE LOW 
    		setPORT |= CE; 		//CE HIGH
    
    		PrintString(">");
    
    		adr++;
    	}
    }
    
    int main(void)
    {
    	InitMEM();
    	
    
    	InitRS();
    	RSspeed(19200);
    
    	PrintString("\r\n\r\n\r\n-------  START  ------- \r\n\r\n");
    
    	write_mem(-1,0xFF);
    
    	_delay_ms(200);
    	
    	read_mem(-1);
    
    	PrintString("\r\n\r\n--------  END  -------- \r\n");
    
    	while(1);
    
    	return 0;
    }
    


    Program an na razie jest w stanie odczytać jeden pierwsze 256 bajtów zapisanych w pamięci. Teoretycznie te same 256 bajtów powinien być w stanie zapisać.

    Problem jest w tym, że nie działa zapis. Co do odczytu tez mam wątpliwości, bo w zależności od ustawienia !CE i OE! zwraca mi różne wartości. Co do zapisu to w ogóle nie działa bo odczyt ciągle zwraca te same wartości co przed zapisem.

    Odpowiedź układu w terminalu RS-232:
    
    -------  START  ------- 
    
    
    
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    >>>>>>>>>>>>>>>>>>>>>
    
      0   0   0   0   0   0   0   0   0   0   0 
      0   0   0   0   0  32  32  32  32  32  32 
     32  96  32  32  32  96  32  96 224  96   0 
      0   0   0   0   0   0   0   0   0   0   0 
      0   0   0   0  32  32  32  96  32 224 224 
     96  32  96 224  96 224  96  96  96   0   0 
      0   0   0   0   0   0   0   0   0   0   0 
      0   0   0  32  32  32 224  32 224 224  96 
     32  96 224  96 224  96  96  96   0   0   0 
      0   0   0   0   0   0   0   0   0   0   0 
      0   0  32 224 224  96 224  96 224  96 224 
     96  96  96 224  96  96  96   0   0   0   0 
      0   0   0   0   0   0   0   0   0   0   0 
      0  32  32  32  96  32 224  96 224  32 224 
    224  96 224  96  96  96   0   0   0   0   0 
      0   0   0   0   0   0   0   0   0   0   0 
     32 224 224  96 224  96  96  96 224 224 224 
    224  96 224 224  96   0   0   0   0   0   0 
      0   0   0   0   0   0   0   0   0   0  32 
    224 224 224 224  96 224 224 224 224  96 224 
    224 224 224  96   0   0   0   0   0   0   0 
      0   0   0   0   0   0   0   0   0 224  96 
    224 224 224 224 224  96 224 224 224  96  96 
     96 224 
    
    --------  END  -------- 
    


    Wszystkie odczytane wartości w tym momencie to powinny być 0xFF (lub 0, bo podłączyłem odwrotnie linie danych) a są różne.

    Najlepiej jakby ktoś napisał gdzie są błędy. W najgorszym wypadku będę musiał Was poprosić o jakiś gotowy działający kod.

    P.S. Pamięć ta zostalą z czegoś wyciągnięta jakiś czas temu więc raczej nie bezie pusta dlatego wartości odczytanie nie są równe.
  • REKLAMA
  • #2 6690689
    ZbeeGin
    Poziom 39  
    Mogłeś po prostu zapomnieć o sekwencji odblokowywania zapisu, a ta pewnie jest założona jak pamięć to używka. Patrz rozdział 19.
  • #3 6690854
    narasta
    Poziom 21  
    Cześć. Dzięki za odpowiedź. A masz może jakiś gotowy kod? Przynajmniej miałbym pewność, że program (sekwencje sterujące pamięcią) jest dobrze napisany. Dziś tego nie zrobię bo jutro egzamin z maszyn elektrycznych (eh...), ale jutro już spróbuję napisać sekwencję odblokowującą software protecta.

    Nie rozumiem jeszcze jednej rzeczy. Kwestia adresowania. Czy szyna adresu jest 18-bitowa czy 8 bitowa +10 bitów dla sektorów. Jeśli np chce załadować adres 5555 to jak trzeba ustawić linie A0-A7 oraz A8-A17?

    [C] Jak obsługiwać pamięci równoległe PEROM np.AT29C020

    O co chodzi w ostatnim punkcie algorytmu? Do jakiego sektora i jakie dane trzeba tam załadować? Byle co do aktualnego sektora?
REKLAMA