STM32F4 I2C подтверждение отказа - PullRequest
0 голосов
/ 25 февраля 2019

Я пытался использовать мою 32Kb EEPROM.Когда я использую код таким способом,

программа ожидает в while(!(I2C2->SR1 & 0x0002)); строке функции I2C_Read_Data_Pro.После того, как я добавил небольшую задержку между I2C_Write_Data_Pro и I2C_Read_Data_Pro, программа работает.Чего мне не хватает?

int main(){

unsigned char EEPROM_DATA;

McuConfig();                                                                            // Islemci hiz ayari = 168 Mhz 
SysTickBaslat();                                                                    // 0.5 ms'de bir kesme olusacak sekilde ayarlandi
Delay(100);
I2C_Init();                                                                             // I2C Init Edildi
LCD_Init();                                                                             // LCD Init Edildi
I2C_Write_Data_Pro(0x50,_I2C_DEVICE_2BYTE_CHIP_IN_ADD_SIZE,0x01,'B');
I2C_Read_Data_Pro (0x50,_I2C_DEVICE_2BYTE_CHIP_IN_ADD_SIZE,0x01,&EEPROM_DATA);
while(1){
    LCD_Write(LCD_ADDR,"Hello\nNoob:)");
    Delay(1000);
    LCD_Write(LCD_ADDR,"STM32F4\nDiscovery");
    Delay(1000);
}
}

Функция записи:

void I2C_Write_Data_Pro(unsigned char Add,unsigned char ChipInsideAddSize, unsigned int ChipInsideAdd ,unsigned char Data){

if((ChipInsideAddSize == _I2C_DEVICE_1BYTE_CHIP_IN_ADD_SIZE ) && (ChipInsideAdd > 255)){        // Hatali Cip Üzeri Adres Degeri Girilmisse
                                                                                                                                                                                        // Engelle
}
else{
    I2C2->CR1 |= (1UL << 8);                                                                        // Start Bit Gönder.
    while(!(I2C2->SR1 & 0x0001));                                                               // START Sarti Olusmasi Icin Bekle (SB=1)
    I2C2->DR = (Add << 1);                                                                          // 7 Bit Address + Slave Yazma Istegi(0) 
    while(!(I2C2->SR1 & 0x0002));                                                               // Adres Gönderilen Kadar Bekle (ADDR = 1)
    while(!(I2C2->SR2 & 0x0001));                                                           // MSL
    while(!(I2C2->SR1 & 0x0080));                                                               // Data Register'in Bos Olamsini Bekle.(TXE = 1)
    I2C2->DR = (ChipInsideAdd & 0x000F);                                                // Yazma Yapilacak Cihazin Üzerindeki Adresin 1. Byte'i Gönderiliyor
    if(ChipInsideAddSize == _I2C_DEVICE_2BYTE_CHIP_IN_ADD_SIZE){// Eger Yazma Yapilacak Cihazin Üzerindeki Adres Uzunlugu 2 Byte'lik ise
        while(!(I2C2->SR1 & 0x0080));                                                           // Data Register'in Bos Olamsini Bekle.(TXE = 1)
        I2C2->DR = ((ChipInsideAdd & 0x00F0)>>4);                                   // Yazma Yapilacak Cihazin Üzerindeki Adresin 2. Byte'i Gönderiliyor
    }
    while(!(I2C2->SR1 & 0x0080));                                                               // Data Register'in Bos Olamsini Bekle.(TXE = 1)
    I2C2->DR = Data;                                                                                        // Cihaz Üzerindeki Adrese Yazma Islemi Gerceklestiriliyor.
    while(!(I2C2->SR1 & 0x0080));                                                               // Data Register'in Bos Olamsini Bekle.(TXE = 1)
    while(!(I2C2->SR1 & 0x0004));                                                               // Data ransfer Edilene Kadar Bekle.(BTF = 1)
    I2C2->CR1 |= (1UL << 9);                                                                        // Stop Bit Gönder
}

}

Функция чтения:

void I2C_Read_Data_Pro(unsigned char Add,unsigned char ChipInsideAddSize, unsigned int ChipInsideAdd ,unsigned char* IncomingData){

if((ChipInsideAddSize == _I2C_DEVICE_1BYTE_CHIP_IN_ADD_SIZE ) && (ChipInsideAdd > 255)){        // Hatali Cip Üzeri Adres Degeri Girilmisse
                                                                                                                                                                                        // Engelle
}
else{
    I2C2->CR1 |= (1UL << 8);                                                                        // Start Bit Gönder.
    while(!(I2C2->SR1 & 0x0001));                                                               // START Sarti Olusmasi Icin Bekle (SB=1)
    I2C2->DR = (Add << 1);                                                                          // 7 Bit Address + Slave Yazma Istegi(0) 
    while(!(I2C2->SR1 & 0x0002));                                                               // Adres Gönderilen Kadar Bekle (ADDR = 1)
    while(!(I2C2->SR2 & 0x0001));                                                           // MSL
    while(!(I2C2->SR1 & 0x0080));                                                               // Data Register'in Bos Olamsini Bekle.(TXE = 1)
    I2C2->DR = (ChipInsideAdd & 0x000F);                                                // Yazma Yapilacak Cihazin Üzerindeki Adresin 1. Byte'i Gönderiliyor
    if(ChipInsideAddSize == _I2C_DEVICE_2BYTE_CHIP_IN_ADD_SIZE){// Eger Yazma Yapilacak Cihazin Üzerindeki Adres Uzunlugu 2 Byte'lik ise
        while(!(I2C2->SR1 & 0x0080));                                                           // Data Register'in Bos Olamsini Bekle.(TXE = 1)
        I2C2->DR = ((ChipInsideAdd & 0x00F0)>>4);                                   // Yazma Yapilacak Cihazin Üzerindeki Adresin 2. Byte'i Gönderiliyor
    }
    while(!(I2C2->SR1 & 0x0080));                                                               // Data Register'in Bos Olamsini Bekle.(TXE = 1)


    I2C2->CR1 |= (1UL << 8);                                                                        // Start Bit Gönder.
    while(!(I2C2->SR1 & 0x0001));                                                               // START Sarti Olusmasi Icin Bekle (SB=1)
    I2C2->DR = (Add << 1) | 0x01;                                                               // 7 Bit Address + Slave Okuma Istegi(1)
    while(!(I2C2->SR1 & 0x0002));                                                               // Adres Gönderilen Kadar Bekle (ADDR = 1)
    while(!(I2C2->SR2 & 0x0001));                                                           // MSL
    while(!(I2C2->SR1 & 0x0040));                                                               // Data Gelene Kadar Bekle.(RXNE = 1)
    *IncomingData = I2C2->DR;                                                                       // Alinan Datayi Gösterilen Adrese Kaydet
    I2C2->CR1 |= (1UL << 9);                                                                        // Stop Bit Gönder
}

}

Редактировать: Я проанализировал шинус логическим анализатором, и я сделал этот скриншот, когда не было задержки между функциями записи и чтения.

https://ibb.co/dLkL7J3

Редактировать 2: Решено, проблема не в stm32.Я использую 24c32 EEPROM, поэтому, когда я просматриваю таблицу данных, она говорит, что должно быть не менее 10 мс свободного времени шины между битом последней остановки и битом следующего запуска.

https://ibb.co/6m3rTPr https://ibb.co/VQW56k9

1 Ответ

0 голосов
/ 25 февраля 2019

У меня недавно была такая же проблема, и состояния ожидания ее решали (не решая).Получилось так, как я ждал, когда флаг статуса оказался неправильным.Поэтому убедитесь, что: 1- Вы очищаете флаг, как только он обнаружен. 2- Вы ждете правильного бита. 3- Вы делаете вышеупомянутое правильно. Например, я не вижу, где в вашем коде вы очищаете бит регистра состояния.после while(!(I2C2->SR1 & 0x0002)); заявления

...