Я пытался использовать мою 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