Forum: Mikrocontroller und Digitale Elektronik STm32F0 und 1Mbit I2C EEprom


von Jens Wörmann (Gast)


Lesenswert?

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

von Jens Wörmann (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.