Ich entwickle eine Bibliothek für I2C eeprom at24c04 mit stm32f030c8 . Meine Lese- und Schreibfunktionen funktionieren, aber wenn ich versuche, unmittelbar nach einem Schreibvorgang in das Eeprom zu lesen, gibt das Eeprom keine Daten zurück. aber ich könnte sofort hintereinander schreiben. Das Problem tritt nur auf, wenn ich nach einer Schreibanweisung lese. Ich habe versucht, das I2C-Aktivierungsbit zu aktivieren und zu deaktivieren, aber das Problem besteht weiterhin. Kann mir jemand sagen, was das Problem ist.
void main()
{
Configure_GPIO_I2C2();
Configure_I2C2_Master(0xA0,1);
I2C_WriteByte(5,'k');
charr= I2C_ReadByte(5);//the program get stuck here because no byte is
//received from eeprom
UART_Send_String(1,&charr);
}
void I2C_WriteByte(uint8_t addr,uint8_t bytetowrite)
{
I2C2->ISR=0x01;
I2C2_StartWrite(2);//start
I2C2->TXDR = addr;//write addr
while(!(I2C2->ISR & I2C_ISR_TXE));
//I2C2_StartWrite(1);
I2C2->TXDR = bytetowrite;
while(!(I2C2->ISR & I2C_ISR_TXE));
I2C2->CR2 |= I2C_CR2_STOP;//stop
while(I2C2->CR2 & I2C_CR2_STOP);
}
uint8_t I2C_ReadByte(uint8_t byteToRead)
{
I2C2->ISR=0x01;
I2C2_StartWrite(1);
I2C2->TXDR = byteToRead;
while(!(I2C2->ISR & I2C_ISR_TXE));
I2C2_StartRead(1);
while(!(I2C2->ISR & I2C_ISR_RXNE));
UART_Send_String(1,"r strt");
uint8_t recv_data=I2C2->RXDR;
I2C2->CR2 |= I2C_CR2_STOP;
while(I2C2->CR2 & I2C_CR2_STOP);
return recv_data;
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
void Configure_GPIO_I2C2(void)
{
RCC->AHBENR |= RCC_AHBENR_GPIOFEN;
GPIOF->MODER |= (2<<12) | (2<<14);
GPIOF->OTYPER |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7;
GPIOF->OSPEEDR &= ~(1<<12);
GPIOF->OSPEEDR &= ~(1<<14);
GPIOF->PUPDR &= ~(1<<12);
GPIOF->PUPDR &= ~(1<<12);
}
void Configure_I2C2_Master(uint8_t slave_addr,uint8_t no_of_bytes)
{
RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;
/* (1) Timing register value is computed with the AN4235 xls file,
fast Mode @400kHz with I2CCLK = 48MHz, rise time = 140ns, fall time = 40ns */
I2C2->CR1 &= ~I2C_CR1_PE;
I2C2->TIMINGR |= (uint32_t)0x00B01A4B; /* (1) */
I2C2->CR2 |= (uint8_t)slave_addr;
I2C2->CR2 |= no_of_bytes<<16;
I2C2->CR1 |= I2C_CR1_PE;
//NVIC_SetPriority(I2C2_IRQn, 0); /* (7) */
//NVIC_EnableIRQ(I2C2_IRQn); /* (8) */
}
void I2C2_StartWrite(int bytesToWrite)
{
I2C2->CR2 &= ~I2C_CR2_RD_WRN;
I2C2->CR2 |= bytesToWrite<<16;
I2C2->CR2 |= I2C_CR2_START;
while(I2C2->CR2 & I2C_CR2_START);
}
void I2C2_StartRead(int bytesToRead)
{
I2C2->CR2 |= I2C_CR2_RD_WRN;
I2C2->CR2 |= bytesToRead<<16;
I2C2->CR2 |= I2C_CR2_START;
while(I2C2->CR2 & I2C_CR2_START);
}
Meine Lese- und Schreibfunktionen funktionieren, aber wenn ich versuche, sofort nach einem Schreibvorgang in das Eeprom zu lesen, gibt das Eeprom keine Daten zurück. aber ich könnte sofort hintereinander schreiben.
Das riecht, als ob Sie nicht darauf warten, dass das EEPROM den Schreibvorgang beendet. Ich habe mir Ihr EEPROM nicht angesehen, aber bei allen, die ich jemals verwendet habe, startet eine Schreib- oder Löschsequenz nur die Aktion. Das EEPROM ist dann noch einige Zeit beschäftigt.
Die meisten EEPROMs haben so etwas wie ein Statusregister, in dem Sie ein wenig abfragen können, ob es beschäftigt ist. Diese Leseaktion kann durchgeführt werden, ob besetzt oder nicht.
Die allgemeinste Softwarearchitektur fragt immer das Busy-Bit ab, bevor sie versucht, irgendetwas zu tun. Wenn das EEPROM beschäftigt ist, fährt es mit der Abfrage fort, bis dies nicht mehr der Fall ist, und fährt dann mit der angeforderten Aktion fort. Anspruchsvollere Implementierungen setzen beim Schreiben und Löschen ein Flag, das anzeigt, dass das EEPROM möglicherweise beschäftigt ist. Die Besetztprüfung wird nur durchgeführt, wenn dieses Flag gesetzt ist. Naive Implementierungen warten immer nur nach einem Löschen oder Schreiben.
Sehen Sie sich Ihren Code genau an, insbesondere was genau an das EEPROM gesendet wird, wenn auf einen Schreibvorgang unmittelbar ein Lesevorgang folgt. Meine Vermutung ist, dass die Besetztprüfung in diesem Fall irgendwie übersprungen wird.
Ich habe die Lesefunktion in zwei Zyklen geändert, einen Schreibvorgang zum Laden der Leseadresse und einen Lesevorgang für die aktuelle Adresse. Es funktioniert jetzt. Ich bin mir jedoch nicht sicher, warum der im Datenblatt erwähnte Lesezyklus für zufällige Adressen nicht funktioniert.
DiBosco
Nikhil Ben George
DiBosco
Nikhil Ben George
DiBosco
Nikhil Ben George
DiBosco
Nikhil Ben George