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

Nie mogę zapisać nieparzystych wartości w EEPROM 24c512 z ATmega8

vonteq666 23 Paź 2006 21:50 1527 2
REKLAMA
  • #1 3146724
    vonteq666
    Poziom 13  
    Posty: 72
    Pomógł: 4
    Ocena: 1
    Witam wszystkich!

    Tak jak w tytule mam problem z wykonaniem operacji WRITE na pamięci EEPROM. Problem polega na tym iż parzyste wartości mogę zapisywać bezproblemowo, nieparzysych nie mogę wogóle zapisać. Pamięć jest podłączona do ATmega8 (piny w listingu). Od trzech dni główkuję nad tym co może być nie tak... Operacja zapisu działa chyba poprawnie. (Zweryfikowałbym to gdyby któryś z kolegów polecił mi jakiś programator tego EEPROM'a pod LPT)

    Oto kod:
    /**Macros & Variables************************************/
    #define EEPROM_PORT 	PORTC
    #define EEPROM_PORT_I	PINC
    #define EEPROM_DDR  	DDRC
    
    #define EEPROM_SDA		0x01
    #define EEPROM_SCK		0x02
    
    #define EEPROM_HDR		0xA0
    
    #define EEPROM_READ		0x01
    #define EEPROM_WRITE	0x00
    
    /**Declarations*****************************************/
    void EEPROMInit();
    void EEPROMWriteByte(short EEPROMAddress, int Address, int Byte);
    short EEPROMReadByte(short EEPROMAddress, int Address);
    short EEPROMCommand(short Byte, short EEPROMAdderss);
    
    void EEPROMBeginTransmition();
    void EEPROMStopTransmition();
    short EEPROMTransmit(short Byte);
    /**Definitions******************************************/
    void EEPROMInit()
    {
    	EEPROM_DDR |= EEPROM_SDA + EEPROM_SCK;	
    }
    
    void EEPROMBeginTransmition()
    {
    	EEPROM_PORT |= EEPROM_SDA;
    	EEPROM_PORT |= EEPROM_SCK;
    	EEPROM_PORT &= ~EEPROM_SDA;
    	EEPROM_PORT &= ~EEPROM_SCK;
    }
    
    void EEPROMStopTransmition()
    {
    	EEPROM_PORT &= ~EEPROM_SDA;
    	EEPROM_PORT |= EEPROM_SCK;
    	EEPROM_PORT |= EEPROM_SDA;
    }
    
    short EEPROMTransmit(short Byte)
    {
    	short i;
    	short Acknowledge = 0;
    	
    	EEPROM_DDR |= EEPROM_SDA;
    	
    	for(i = 7; i >= 0; i--)
    	{
    		
    		if(Byte & (1 << i))
    		{
    			EEPROM_PORT |= EEPROM_SDA;
    		}
    		
    		else
    		{
    			EEPROM_PORT &= ~EEPROM_SDA;
    		}
    		_delay_us(400);
    		EEPROM_PORT |= EEPROM_SCK;
    		_delay_us(400);
    		EEPROM_PORT &= ~EEPROM_SCK;
    		_delay_us(400);
    	}
    	
    	
    	EEPROM_DDR &= ~EEPROM_SDA;
    	
    	//if(!(EEPROM_PORT_I & EEPROM_SDA))
    
    	EEPROM_PORT |= EEPROM_SCK;
    	EEPROM_PORT &= ~EEPROM_SCK;
    	EEPROM_DDR |= EEPROM_SDA;
    
    	return Acknowledge;
    }
    
    
    
    	
    short EEPROMReceive()
    {
    	short i, Data = 0;
    	
    	EEPROM_DDR &= ~EEPROM_SDA;
    	
    	for(i = 7; i >= 0; i--)
    	{
    		//_delay_us(400);
    		
    		if(EEPROM_PORT_I & EEPROM_SDA)
    		{
    			Data |= (1 << i);
    		}
    		
    		EEPROM_PORT |= EEPROM_SCK;
    		//_delay_us(400);
    		EEPROM_PORT &= ~EEPROM_SCK;
    	}
    	
    	//while(!(EEPROM_PORT_I & EEPROM_SDA));
    	
    	EEPROM_PORT |= EEPROM_SCK;
    	//_delay_us(400);
    	EEPROM_PORT &= ~EEPROM_SCK;
    	
    	EEPROM_DDR |= EEPROM_SDA;
    	
    	return Data;
    }
    	
    	
    short EEPROMCommand(short Command, short EEPROMAddress)
    {
    	short Byte = EEPROM_HDR + EEPROMAddress + (Command & 0x01);	
    	return EEPROMTransmit(Byte);
    }
    
    void EEPROMWriteByte(short EEPROMAddress, int Address, int Byte)
    {
    	EEPROMBeginTransmition();
    	EEPROMCommand(EEPROM_WRITE, EEPROMAddress);
    	EEPROMTransmit(Address >> 8);
    	EEPROMTransmit(Address & 0xFF);
    	EEPROMTransmit(Byte & 0xFF);
    	EEPROMStopTransmition();
    	_delay_ms(30);
    }
    	
    	
    short EEPROMReadByte(short EEPROMAdderss, int Address)
    {
    	short Data;
    	
    	EEPROMBeginTransmition();
    	EEPROMCommand(EEPROM_WRITE, EEPROMAdderss);
    	EEPROMTransmit(Address >> 8);
    	EEPROMTransmit(Address & 0xFF);
    	_delay_ms(30);
    	EEPROMBeginTransmition();
    	EEPROMCommand(EEPROM_READ, EEPROMAdderss);
    	Data = EEPROMReceive();	
    	EEPROMStopTransmition();
    	
    	return Data;
    }	
    	
  • REKLAMA
  • Pomocny post
    #2 3146992
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Ciesz się , że to wogóle działa :D
    Przypatrz sie 1-szej linii i napisz , czy po jej wykonaniu linia SDA będzie rzeczywiście w stanie niskim :?:
    
    void EEPROMStopTransmition()
    {
    	EEPROM_PORT |= ~EEPROM_SDA; //*****************
    	EEPROM_PORT |= EEPROM_SCK;
    	EEPROM_PORT |= EEPROM_SDA;
    }
    


    Piotrek
  • #3 3147123
    vonteq666
    Poziom 13  
    Posty: 72
    Pomógł: 4
    Ocena: 1
    Ale gafa! :D Dziękuję ślicznie za pomoc! Jednak nie ma to jak ktoś kto "świeżym" okiem spojrzy na kod ;)

    Pomimo błędu w funkcji StopTransmition(); kod umożliwiał odczyt z pamięci EEPROM. Powodem tego był fakt iż pamięć po otrzymaniu rozkazu RANDOM READ zwraca tylko jeden bajt po czym sama kończy transmisję nawet jeśli funkcja StopTransmition nie zostanie wywołana.BYTE WRITE zaś przyjmuje argumenty dopóki nie wystąpi StopTransmition, który z racji błędu nigdy tak naprawdę nie wystąpił i dlatego zapisywanie było z lekka "nie-w-pełni-sprawne" :)

    Pozdrawiam i zapraszam do korzystania z kodu (błąd już poprawiony)

    Tomek
REKLAMA