ext. RAM 23LC1024

trix

Golden Member

goedendag,

ik maak voor een groter project gebruik van een externe RAM de 23LC1024.
hier schrijf ik de data in die ik met een "scanner" heb verkregen.
in de ext. RAM maak ik gebruik van de "Sequential mode" dit wil zeggen:
je geeft het begin adres op en stuurt daar alle bytes achteraan, het adres in de ext. RAM word dan elke keer met 1 op gehoogd.

dat werkt,.....alleen bij de 1e keer na spanning op het geheel.
als ik de 2e keer weer data v/d "scanner" naar de RAM verstuur, dan schuift de data in de RAM op met ongeveer 14 bits op. terwijl ik wel hetzelfde start adres opgeef. dit is te zien in de 2x printscreen. het gele lijntje is het begin van de 1e keer, in het gele cirkeltje word dit nog cijfer matig weer gegeven.
ik kan in dedatasheet v/d 23LC1024 (ext. RAM) ook niet iets vinden wat dit verklaart.
ik denk dat ik iets relatiefs simpel over het hoofd zie.
wie heeft er een goed hint voor mij, waarvoor alvast mijn dank _/-\o_

eigenwijs = ook wijs

Een test functie voor schrijven (losstaand van je scan programma), om de rest van je systeem uit te kunnen sluiten.

Daarnaast valt het mij op dat het einde blijkbaar wel ongeveer klopt.

In een testfunctie kan je bijvoorbeeld op iedere byte een (deel van) zijn eigen adres wegschrijven.

PA0EJE - www.eje-electronics.nl - e.jongerius[aapje]eje-electronics.nl - EJE Electronics - Elektronica/firmware ontwikkeling
trix

Golden Member

nee het einde klopt ook niet, is hier vertekend omdat ik verschillend heb gescaled in paint.

ik zal de code eens bijvoegen waar naar de RAM word geschreven.

eerst de ISR:

c code:


volatile int receivedbyte					= 0;         // needed for incoming data from TSOP's
volatile int TSOP_byte_transfer_counter		= 0;
volatile int transfer_ready					= 0;

ISR(USART0_RX_vect)                                      // receving data from TSOP's and write in to ext. RAM
{	
	receivedbyte = UDR0;                                 // copy the received byte value into the variable "receivedbyte"	
	TSOP_byte_transfer_counter += 1;
	
	if (TSOP_byte_transfer_counter == 299)
	{
		transfer_ready = 1;
	}
		
	_delay_us(50);                                       // just for testing ******************************************	

	SPDR = receivedbyte;                                 // data what you write in the ext. RAM
	while(!(SPSR & (1<<SPIF)));                          // Wait for transmission complete			
}

c code:


for (scanner_read = 0; scanner_read < 5; scanner_read ++) // for reading all the TSOP's to the MAIN pcb.
{		
// ******************************************************************************************************		
// *** below: byte 1 ************************************************************************************
// ******************************************************************************************************
					
	PORTE |= (1 << PINE2); // switch MAX485 as transmitter pin 2 & 3 = "1"
	PORTE |= (1 << PINE3); // switch MAX485 as transmitter pin 2 & 3 = "1"					
					
	UCSR0B |= (1 << TXB80); //Set the TXB8 bit (9e bit) to 1: we gonna send a addres
	
// *** adress numbering: TSAL 1-20 and TSOP 21-40 *******************************************************

	TSOP_adres = scanner_read + 21;			
	
	_delay_ms(1);
	while ((UCSR0A & (1 << UDRE0)) == 0) {}; // do nothing till the UDR is ready to receive
	bytetosend = TSOP_adres; // is the adress TSOP
	UDR0 = bytetosend;		
							
	_delay_ms(100);
	while ((UCSR0A & (1 << UDRE0)) == 0) {}; // do nothing till the UDR is ready to receive
	bytetosend = 0b00000001; // is the data: TSOP send your data 1e byte to me.
	UDR0 = bytetosend;					
				
	_delay_ms(1);
	while ((UCSR0A & (1 << UDRE0)) == 0) {}; // do nothing till the UDR is ready to receive
	bytetosend = 0b11111111; // is the data witch is the stop code
	UDR0 = bytetosend;			
			
	tsop_request_send_your_data_to_me_finished = 1; // used in interrupt, changed PINE2 & PINE3	to "0"				
			 
	UCSR0A &= ~(1 << MPCM0); // switch off the MPCM mode for receiving data		
			 			
// *** below: putting the data from the TSOP in to the ext. RAM ******************************************
						
	PORTG &= ~(1 << PING5); // make SS ext. RAM pin = 0						
						
	RAM_adress = ((scanner_read * 3000) + 1);						
			
	SPI_transfer(0b00000010);  // write data to memory
	address = RAM_adress; // is address in ext. RAM
			
	SPI_transfer((address>>16)); // adress
	SPI_transfer((address>>8));  // adress
	SPI_transfer((address));     // adress
						
	PORTH |= (1 << PINH7); // LED = 1 just for checking ROOD ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
						
	TSOP_byte_transfer_counter = 0; // incr. in the ISR. if 300 bytes are in make variable "0												
			
	while (transfer_ready == 0) // doing loop until 300 bytes are in. ^^^^^^^^^^^^^^^^^^^^
	{
		// TSOP_byte_transfer_counter is increased in the ISR
		// data is there also written to the ext. RAM  								
	}						
					
	transfer_ready = 0;
												
	PORTG |= (1 << PING5); // make SS ext. RAM pin = 1															
	PORTH &= ~(1 << PINH7); // LED = 0 just for checking ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^					
						
// ******************************************************************************************************			
// *** below: byte 2 ************************************************************************************
// ******************************************************************************************************
	PORTE |= (1 << PINE2); // switch MAX485 as transmitter pin 2 & 3 = "1"
	PORTE |= (1 << PINE3); // switch MAX485 as transmitter pin 2 & 3 = "1"
			
	UCSR0B |= (1 << TXB80); //Set the TXB8 bit (9e bit) to 1: we gonna send a addres
			
	// *** adress numbering: TSAL 1-20 and TSOP 21-40 *******************************************************

	TSOP_adres = scanner_read + 21;								
				
	_delay_ms(1);
	while ((UCSR0A & (1 << UDRE0)) == 0) {}; // do nothing till the UDR is ready to receive
	bytetosend = TSOP_adres; // is the adress TSOP
	UDR0 = bytetosend;
			
	_delay_ms(100);
	while ((UCSR0A & (1 << UDRE0)) == 0) {}; // do nothing till the UDR is ready to receive
	bytetosend = 0b00000010; // is the data: TSOP send your data 2e byte to me.
	UDR0 = bytetosend;
			
	_delay_ms(1);
	while ((UCSR0A & (1 << UDRE0)) == 0) {}; // do nothing till the UDR is ready to receive
	bytetosend = 0b11111111; // is the data witch is the stop code
	UDR0 = bytetosend;
			
	tsop_request_send_your_data_to_me_finished = 1; // used in interrupt, changed PINE2 & PINE3	to "0"
			
	UCSR0A &= ~(1 << MPCM0); // switch off the MPCM mode for receiving data			

// *** below: putting the data from the TSOP in to the ext. RAM ******************************************
						
	PORTG &= ~(1 << PING5); // make SS ext. RAM pin = 0								
			
	RAM_adress = (((scanner_read * 3000) + 1) + 1000);						
						
	SPI_transfer(0b00000010);  // write data to memory
	address = RAM_adress; // is address in ext. RAM
			
	SPI_transfer((address>>16)); // adress
	SPI_transfer((address>>8));  // adress
	SPI_transfer((address));     // adress
						
	PORTB |= (1 << PINB7); // LED = 1 just for checking GEEL ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
						
	TSOP_byte_transfer_counter = 0; // incr. in the ISR. if 300 bytes are in make variable "0"
						
	while (transfer_ready == 0) // doing loop until 300 bytes are in. ^^^^^^^^^^^^^^^^^^^^
	{
		// TSOP_byte_transfer_counter is increased in the ISR
		// data is there also written to the ext. RAM
	}						
					
	transfer_ready = 0;
													
	PORTG |= (1 << PING5); // make SS ext. RAM pin = 1
	PORTB &= ~(1 << PINB7); // LED = 0 just for checking ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^									
						
// ******************************************************************************************************
// *** below: byte 3 ************************************************************************************
// ******************************************************************************************************
	PORTE |= (1 << PINE2); // switch MAX485 as transmitter pin 2 & 3 = "1"
	PORTE |= (1 << PINE3); // switch MAX485 as transmitter pin 2 & 3 = "1"

	UCSR0B |= (1 << TXB80); //Set the TXB8 bit (9e bit) to 1: we gonna send a addres

	// *** adress numbering: TSAL 1-20 and TSOP 21-40 *******************************************************

	TSOP_adres = scanner_read + 21;
    	
	_delay_ms(1);
	while ((UCSR0A & (1 << UDRE0)) == 0) {}; // do nothing till the UDR is ready to receive
	bytetosend = TSOP_adres; // is the adress TSOP
	UDR0 = bytetosend;

	_delay_ms(100);
	while ((UCSR0A & (1 << UDRE0)) == 0) {}; // do nothing till the UDR is ready to receive
	bytetosend = 0b00000011; // is the data: TSOP send your data 3e byte to me.
	UDR0 = bytetosend;

	_delay_ms(1);
	while ((UCSR0A & (1 << UDRE0)) == 0) {}; // do nothing till the UDR is ready to receive
	bytetosend = 0b11111111; // is the data witch is the stop code
	UDR0 = bytetosend;

	tsop_request_send_your_data_to_me_finished = 1; // used in interrupt, changed PINE2 & PINE3	to "0"

	UCSR0A &= ~(1 << MPCM0); // switch off the MPCM mode for receiving data

// *** below: putting the data from the TSOP in to the ext. RAM ******************************************
						
	PORTG &= ~(1 << PING5); // make SS ext. RAM pin = 0						
			
	RAM_adress = (((scanner_read * 3000) + 1) + 2000);

	SPI_transfer(0b00000010);  // write data to memory
			address = RAM_adress; // is address in ext. RAM

	SPI_transfer((address>>16)); // adress
	SPI_transfer((address>>8));  // adress
					
	PORTG |= (1 << PING4); // relay = 1 just for checking  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
						
	TSOP_byte_transfer_counter = 0; // incr. in the ISR. if 300 bytes are in make variable "0"												

	while (transfer_ready == 0) // doing loop until 300 bytes are in. ^^^^^^^^^^^^^^^^^^^^
	{
		// TSOP_byte_transfer_counter is increased in the ISR
		// data is there also written to the ext. RAM
	}						
					
	transfer_ready = 0;
													
	PORTG |= (1 << PING5); // make SS ext. RAM pin = 1
	PORTG &= ~(1 << PING4); // LED = 0 just for checking RELAY ^^^^^^^^^^^^^^^^^^^^^^^^^^										
						
} // from: for(scanner_read................	

[Bericht gewijzigd door trix op 31 juli 2021 10:22:13 (97%)]

eigenwijs = ook wijs

Blijft het bij meer als twee keer daarna wel stabiel en gelijk aan de 2e scan?

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com
trix

Golden Member

nee, hij schuift steeds weer een stukje op, en dat stukje is ook niet iedere keer gelijk, ik heb nu 13 15 en 16 bits (kolommen) gezien.

[Bericht gewijzigd door trix op 31 juli 2021 12:01:19 (53%)]

eigenwijs = ook wijs
mel

Golden Member

zit er ergens een stukje geheugen dat het beginadres onthoud,en dit er bij optelt?

u=ir betekent niet :U bent ingenieur..
trix

Golden Member

weet ik zo niet, staat niet in de datasheet.

eigenwijs = ook wijs

Heb je de SPI bus goed ingesteld?
Kan me voorstellen als de clock polariteit, phase of edge niet goed hebt ingesteld je een bitje kan missen aan het begin of einde van een write/read cycles.

trix

Golden Member

maar dan krijg je denk ik andere symphtonen.

eigenwijs = ook wijs

Ik zou eerst een testroutine maken, die een vast patroon naar een vaste geheugenplaats(en) schrijft.
Nu weet je niet of het scannen, schrijven, of lezen fout gaat...

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

heb je al eens gekeken naar de chip select van de RAM.
Ik heb je code niet gelezen, maar ik denk dat die mbhv een GPIO output gemaakt wordt.
Als de Chip select aktief / deaktief wordt op het moment dat de SPI pheripereral nog aan het schuiven is, kun je rare dingen verwachten.

trix

Golden Member

ja, mischien dat ik een test routine moet maken om te zien waar het fout gaat. even kijken hoe ik dit het best kan doen.
chip select, stuur ik dacht ik wel goed aan, maar ik ga day ook nog eens bekijken tnx.

eigenwijs = ook wijs

en dat stukje is ook niet iedere keer gelijk, ik heb nu 13 15 en 16 bits (kolommen) gezien.[/quote]
Maar het is vrij simpel als je ineens een aantal bits bent opgeschoven dan heeft het geheugen dat gedaan als reactie op even zoveel klokpulsen die het heet gezien en de kans dat microchip een bug in de chip heeft lijkt me uitgesloten en dus moet het wel in je software zitten.

Dus nadat je het adress heb geselecteerd moet er voor elke klokpuls die je geef er ook een bit waarde worden verstuurd. Mijn gok is dat je nu 14 keer of 15 teveel een klokpuls stuurt. Of dat bewust is of Omdat je vergeet op tijd de chipselect lijn uit te zetten waardoor het geheugen ergens zelf een klok oppikt is me niet duidelijk.

c code:

	SPI_transfer(0b00000010);  // write data to memory
	address = RAM_adress; // is address in ext. RAM
			
	SPI_transfer((address>>16)); // adress
	SPI_transfer((address>>8));  // adress
	SPI_transfer((address));     // adress

Ik kan hierna nergens zien in je code dat je ook de SPI transfer stopt of dat je de chipselect uitzet.

Zet in je ISR eens dit:

code:


ISR(USART0_RX_vect)                                      // receive data from TSOP's and write in to ext. RAM
{	
	receivedbyte = UDR0;                                 // copy the received byte value into the variable "receivedbyte"	
	SPDR = receivedbyte;                                 // data what you write in the ext. RAM
	while(!(SPSR & (1<<SPIF)));                          // Wait for transmission complete			

	TSOP_byte_transfer_counter += 1;
	
	if (TSOP_byte_transfer_counter == 299)
	{
		transfer_ready = 1;
	}
		
	_delay_us(50);                                       // just for testing ******************************************	


}

Je transfer ready wordt denk ik te vroeg gezet, je main loop loopt dan te vroeg als een kip zonder kop door. En haal er die delay ook uit!
Waarschijnlijk is het niet het probleem, maar zo is het wel "beter" mocht je meerdere interrupts hebben lopen.

Henri's Law 1: De wet van behoud van ellende. Law 2: Ellende komt nooit alleen.
trix

Golden Member

ga ik testen, maar ik ga eerst een weekje met vakantie.
bedankt voor de hulp, en mochten er nog meer mensen op vakantie gaan:
een prettige vakantie toegewenst.

eigenwijs = ook wijs