Estoy desarrollando una biblioteca para I2C eeprom at24c04 con stm32f030c8 . Mis funciones de lectura y escritura funcionan, pero cuando trato de leer inmediatamente después de escribir en la eeprom, la eeprom no devuelve ningún dato. sin embargo, podría hacer inmediatamente una escritura consecutiva. El problema ocurre solo cuando leo después de una declaración de escritura. Intenté habilitar y deshabilitar el bit de habilitación de I2C pero el problema aún existe. ¿Alguien puede decirme cuál es el problema?
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);
}
Mis funciones de lectura y escritura funcionan, pero cuando trato de leer inmediatamente después de escribir en la eeprom, la eeprom no devuelve ningún dato. sin embargo, podría hacer inmediatamente una escritura consecutiva.
Parece que no estás esperando que la EEPROM termine de escribir. No miré tu EEPROM, pero con todas las que he usado, una secuencia de escritura o borrado solo inicia la acción. Luego, la EEPROM está ocupada durante algún tiempo.
La mayoría de las EEPROM tienen algo así como un registro de estado donde puede sondear un poco para ver si está ocupado. Esta acción de lectura se puede realizar tanto si está ocupado como si no.
La arquitectura de software más general siempre sondea el bit ocupado antes de intentar hacer algo. Si la EEPROM está ocupada, sigue sondeando hasta que no lo está, luego continúa con la acción que se solicitó. Las implementaciones más sofisticadas establecen un indicador de escritura y borrado, lo que indica que la EEPROM podría estar ocupada. La verificación de ocupado solo se realiza cuando se establece este indicador. Las implementaciones ingenuas siempre solo esperan después de borrar o escribir.
Mire su código cuidadosamente, especialmente qué es exactamente lo que se envía a la EEPROM cuando una escritura es seguida inmediatamente por una lectura. Mi conjetura es que la verificación ocupada se omite de alguna manera en ese caso.
Modifiqué la función de lectura en dos ciclos, una escritura para cargar la dirección de lectura y una lectura de la dirección actual. Está funcionando ahora. Sin embargo, no estoy seguro de por qué el ciclo de lectura de direcciones aleatorias como se menciona en la hoja de datos no funciona.
dibosco
Nikhil Ben George
dibosco
Nikhil Ben George
dibosco
Nikhil Ben George
dibosco
Nikhil Ben George