STM32F4 i2c PCF8574T Port Çoğaltma

Başlatan SahinCeylan, 08 Aralık 2019, 14:23:27

SahinCeylan

Merhabalar, stm32f4 kartı ile std periph kütüphanelerini kullanarak pcf8574t modülü vasıtası ile port çoğaltma üzerine bir çalışma yapıyorum. Fakat problemi çözemedim. PCF8574T bağlamış olduğum 7 adet ledler öncelikle soluk yanıyor başlangıç durumunda. Kodu debug yaptığımda ise " I2C_SendData(I2C1, data); " kodundan sonra kod kilitleniyor ve çalışmadığını gördüm. Kütüphanede  kullanım  tarzı vs hepsini uygulamama rağmen çalışmıyor. Lojik analizör ile inceleme yapıyorum fakat oradada sonuç alamadım haberleşme olmuyor. PCF8574T'nin adres bilgisi için datasheet açıp baktım. 0x4E, 0x27, 0x40, 0x20 adreslerini tek tek denedim. Sonuç yine aynı. Yazdığım kodu aşağıda paylaşıyorum. Acaba nerede hata yaptım?

#include "stm32f4xx.h"
#include "stm32f4_discovery.h"

GPIO_InitTypeDef GPIO_InitStruct;
I2C_InitTypeDef I2C_InitStruct;					// I2C için tanımlanan initstructımız



uint8_t m_adress = 0x4E;					// datasheet 13. sayfada adresler var. buradan aldığımız adresi tanımladık. modülün adresi bu
int i = 0;


void delay(uint32_t time)
{
	while(time--);
}


void GPIO_Config()
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);		// buton için bunu tanımladık
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);		// I2C-1 B portuna fiziksel olarak bağlı olduğu için portun clock hattını tanımladık.

	// buton için config ayarlar yapılıyor
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;

	GPIO_Init(GPIOA, &GPIO_InitStruct);

	// şimdi I2C için config ayarlar yapılıyor.

	GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);		// burada alternative function tanıttık. b portunun 6. numaralı pinin i2c1 seçtik. SCL PİN
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);		// burada alternarive function tanıttık. b portunun 7. numaralı pinin i2c1 seçtik. SDA PİN

	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;					// burada alternative function olduğunu belirttik
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;			// 6 ve 7 numara olduğunu söyledik
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;

	GPIO_Init(GPIOB, &GPIO_InitStruct);							// pinafconfig ince ayarla birlikte topluca yükledik.
}





void I2C_Config()
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);		// i2c1 apb1 clock hattında ve aktif ettik.

	I2C_InitStruct.I2C_Ack = ENABLE;							// birden fazla slave cihaz varsa adres bilgisi ve data bilgisi teyit için aktif ettik.
																// böylece cihaz adresini hatta gönderince cihaz bize evet benim adresim bu diye döner
	I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;	// ack adresi 7 bit olsun dedik.
	I2C_InitStruct.I2C_ClockSpeed = 400000;						// i2c maksimum 400khz frekansa kadar çalışıyor. max frekansı ayarlamış olduk
	I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;				// görev süresi diyede geçer. 2 dedi neden dedi bilmiyorum
	I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;						// i2c modunda kullanıyoruz dedik
	I2C_InitStruct.I2C_OwnAddress1 = 0x00;						// ilk cihazın kendi adresini belirt diyor. biz 0x00 dedik

	I2C_Init(I2C1, &I2C_InitStruct);							// dataları yükledik

	I2C_Cmd(I2C1,ENABLE);										// i2c1 çevresel birim olduğu için aktif ettik.
}



void I2C_Write(uint8_t adress, uint8_t data)					// i2c yazma fonksiyonu hem adres hemde data bilgisini alıyor
{
	while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));				// i2c hattı meşgul olabilir. i2c uygun olana kadar bekle bayrak inince devam et. bayrak 1 ise burada bekle 1 demek meşgul demek

	I2C_GenerateSTART(I2C1, ENABLE);							// i2c1 haberleşmesini başlat dedik.

	while(!(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)));	// i2c1 için master mod seçilene kadar bekle master mod seçilince devam et. çünkü bu cihaz master
	// yukarıda kod ile master moda almış oluyor cihazımızı gibi düşünebilirizz sanırım. master mod seçilmiş ve değili ise devam et diyor yukarıdaki kod

	I2C_Send7bitAddress(I2C1, adress,I2C_Direction_Transmitter);	// burada 7 bitlik adres bilgisini hatta gönderiyoruz. i2c1 için yapıyoruz. adres bilgisi
	// fonksiyona gelen adress değişkeni olacak. ve biz bu datayı gönderdiğimiz için transmitter modunu seçtik. göndereceğimiz slave adresini hatta gönderdik

	while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)));	// şimdi de gönderici olarak hazır hale geldim mi onu bekliyorum. yani adres bilgisini
	// gönderdik hatta o adres sahibine adres ulaştı ise bize geri bildirim ile bilgi vermesini bekliyoruz.

	I2C_SendData(I2C1, data);									// şimdi de hatta datamızı gönderdik.

	I2C_GenerateSTOP(I2C1, ENABLE);								// datayı gönderdikten sonra artık i2c1 haberleşmesini durdurduk.
}


int main(void)
{
	GPIO_Config();
	I2C_Config();

  while (1)
  {
	  if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))
	  {
		  while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0));	// burası 1 olduğu sürece bekle böylece elimiz butona basılı iken bekle kaldırdıktan sonra devam et
		  i++;
		  delay(1680000);
	  }

	  switch(i)
	  {
	  case 0:
		  I2C_Write(m_adress, 0x00);					// burada hiçbirşey yapma bütün pportlar sıfır olsun dedik
		  break;

	  case 1:
		  I2C_Write(m_adress, 0x01);					// case 1 olunca 1. ledi yak dedik
		  break;

	  case 2:
		  I2C_Write(m_adress, 0x02);					// case 2 olunca 2. ledi yak dedik

		  break;

	  case 3:
		  I2C_Write(m_adress, 0x04);					// case 3 olunca 3. ledi yak dedik
		  break;

	  case 4:
		  I2C_Write(m_adress, 0x08);					// case 4 olunca 4. ledi yanmayacak bağlı değil artık 8 den fazla yazamayız 8 bitlik olunca
		  break;

	  case 5:
		  I2C_Write(m_adress, 0x10);					// case 5 olunca 4. ledi yanmayacak bağlı değil artık 8 den fazla yazamayız 8 bitte çalıştığımız için
		  break;

	  case 6:
		  I2C_Write(m_adress, 0x20);					// case 6 olunca 5. ledi yak dedik
		  break;

	  case 7:
		  I2C_Write(m_adress, 0x40);					// case 7 olunca 6. ledi yak dedik
		  break;

	  case 8:
		  I2C_Write(m_adress, 0x80);					// case 8 olunca 7. ledi yak dedik
		  break;
		  	  	  	  	  	  	  	  	  	  	  	  	// 7 tane çıkışımız olduğu için burada durduk
	  default:
		  i=0;
		  break;
	  }
  }
}



void EVAL_AUDIO_TransferComplete_CallBack(uint32_t pBuffer, uint32_t Size){
  /* TODO, implement your code here */
  return;
}

/*
 * Callback used by stm324xg_eval_audio_codec.c.
 * Refer to stm324xg_eval_audio_codec.h for more info.
 */
uint16_t EVAL_AUDIO_GetSampleCallBack(void){
  /* TODO, implement your code here */
  return -1;
}