Hallo,
ich baue auf diesem Thread hier von vor ein paar Tagen auf. Irgendwie
habe ich da gerade Tomaten auf den Augen. Ich habe versucht das auf dem
STM32F030 zu realiseren, aber es läuft nur bedingt.
Und zwar habe ich mehrere Probleme. Zum einen scheint das schreiben nach
Osziloskop zu klappen - beim lesen sieht es fast so aus als würde die
Adresse nicht richtig geschrieben und er dann im Nirvana lesen.
Das andere ist das Warten Problem habe ich beim auf die TXIS Flag - hier
hängt das sich das Ding regelmässig auf. Sprich die TXIS Flag kommt
nicht und es kommt zum Timeout.
Die Write Routine sieht so aus - ich habe dafür eine bestehende Routine
eines kleineren EEProms umgearbeitet:
uint32_t ee_write_page(uint8_t* p_buffer, uint16_t write_addr, uint8_t*
num_byte_to_write)
{
uint32_t data_num = 0;
//Configure slave address, nbytes, reload and generate start
I2C_TransferHandling(I2C_EE, m_ee_address, 1, I2C_Reload_Mode,
I2C_Generate_Start_Write);
//Wait until TXIS flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TXIS) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
//Send memory address
I2C_SendData(I2C_EE, (uint8_t)write_addr);
//Wait until TCR flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TCR) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
#endif
#ifdef MBIT_EEPROM
//Send memory address
uint8_t deviceSelect = 0xA0;
uint16_t add1, add2;
add1 = (write_addr) / EE_PAGESIZE;
add2 = (write_addr) % EE_PAGESIZE;
add1 = (write_addr & 0xFF00) >> 8;
add2 = (write_addr & 0X00FF);
// add or reset A16 to the deveice selection register
deviceSelect |= ee_u8AdressBit16;
m_ee_address = deviceSelect;
//Configure slave address, nbytes, reload and generate start
I2C_TransferHandling(I2C_EE, m_ee_address, 1, I2C_Reload_Mode,
I2C_Generate_Start_Write);
//Wait until TXIS flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TXIS) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
//Send memory address high byte
I2C_SendData(I2C_EE, (uint8_t)add1);
//Wait until TCR flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TCR) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
//Send memory address low byte
I2C_SendData(I2C_EE, (uint8_t)add2);
//Wait until TCR flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TCR) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
add2 = *num_byte_to_write;
#endif
//Update CR2 : set Slave Address , set write request, generate Start
and set end mode
I2C_TransferHandling(I2C_EE, m_ee_address,
(uint8_t)(*num_byte_to_write), I2C_AutoEnd_Mode, I2C_No_StartStop);
while(data_num != (*num_byte_to_write))
{//Wait until TXIS flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TXIS) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
//Write data to TXDR
I2C_SendData(I2C_EE, (uint8_t)(p_buffer[data_num]));
//Update number of transmitted data
data_num++;
}
//Wait until STOPF flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_STOPF) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
//Clear STOPF flag
I2C_ClearFlag(I2C_EE, I2C_ICR_STOPCF);
//If all operations OK, return EE_OK (0)
return EE_OK;
}
Das device select wird, wenn ich es richtig verstanden habe vom STM mit
dem Start mitgeschickt. Zumindest sieht es im Osca so aus.
Für read gilt folgendes:
uint32_t ee_read_buffer(uint8_t* p_buffer, uint16_t read_addr, uint16_t
num_byte_to_read)
{
uint32_t numb_of_single = 0, count = 0, data_num = 0, start_com = 0;
//Get number of reload cycles
count = (num_byte_to_read) / EE_PAGESIZE;
numb_of_single = (num_byte_to_read) % EE_PAGESIZE;
//Configure slave address, nbytes, reload and generate start
I2C_TransferHandling(I2C_EE, m_ee_address, 1, I2C_SoftEnd_Mode,
I2C_Generate_Start_Write);
//Wait until TXIS flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TXIS) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
//Send memory address
I2C_SendData(I2C_EE, (uint8_t)read_addr);
//Wait until TC flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TC) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
#endif
// this is for eeprom types with >= 1 Mbit space */
#ifdef MBIT_EEPROM
uint8_t deviceSelect = 0xA0;
uint16_t add1, add2;
// add1 = (read_addr) / EE_PAGESIZE;
// add2 = (read_addr) % EE_PAGESIZE;
add1 = (read_addr & 0xFF00) >> 8;
add2 = (read_addr & 0X00FF);
// add or reset A16 to the deveice selection register
deviceSelect |= ee_u8AdressBit16;
m_ee_address = deviceSelect;
//Get number of reload cycles
count = (num_byte_to_read) / EE_PAGESIZE;
numb_of_single = (num_byte_to_read) % EE_PAGESIZE;
//Configure slave address, nbytes, reload and generate start
I2C_TransferHandling(I2C_EE, m_ee_address, 1, I2C_SoftEnd_Mode,
I2C_Generate_Start_Write);
//Wait until TXIS flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TXIS) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
//Send memory address high byte
I2C_SendData(I2C_EE, (uint8_t)add1);
//Wait until TC flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TC) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
//Send memory address low byte
I2C_SendData(I2C_EE, (uint8_t)add2);
//Wait until TC flag is set
m_ee_timeout = EE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2C_EE, I2C_ISR_TC) == RESET)
{
if((m_ee_timeout--) == 0)
return ee_timeout_user_callback();
}
Start - und Daten holen...
}
[] Daten holen....
}
Jemand ne Idee was ich falsch mache?
Grüße
Jens
Man sollte auch den Thread angeben auf den man sich bezieht: Beitrag "M24M01 Adressieren" Anmerkung noch: Wenn ich die ganzen While Schleifen, die sich auf TXIS beziehen auskommentiere seh ich zumindest Daten auf dem Bus. Grüße
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.