STM32 kafa yedirten I2C sorunu

Başlatan strom, 05 Ocak 2014, 01:40:57

strom

Herkese iyi günler öncelikle.
Elimdeki stm32f429 discovery kitinde bulunan STMPE811 dokunmatik ekran sürücüsünü kullanmaya çalışırken I2C ile ilgili bir sorunla karşılaştım. Yazdığım kod normalde çalışıyor. Device ID ve versiyonunu okuyorum ancak ne zaman alete reset atsam (debug'a başladığımda veya kitin üzerindeki reset tuşuna bastığımda) kod tekrardan çalışmıyor. Debug'da incelediğimde gördümki hat sürekli meşgul (BUSY biti sürekli 1). Dolayısıyla daha ilk start condition göndermemde alet tıkanıyor ve göndermiyor. Cihaz böyle sapıtmışken elektriği kesip geri veriyorum ve bu seferde çalışıyor. Dediğim gibi reset durumunda çalışmazkan voltajı çekip geri verdiğimde çalışıyor.
Nette baktım I2C modülünü filan resetleyin gibisinden bi kaç öneri vardı. Denedim ama sonuç alamadım. Sizce bu durum neyden kaynaklanıyor olabilir?

muhittin_kaplan

kodu görelim, yorum ancak yaparız

strom

Bu I2C modülünü hazırlayan kod parçası;

RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOCEN, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1ENR_I2C3EN, ENABLE);

	
	GPIO_InitTypeDef mGPIO;
	
	mGPIO.GPIO_Mode = GPIO_Mode_AF;
	mGPIO.GPIO_OType = GPIO_OType_OD;
	mGPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
	mGPIO.GPIO_Speed = GPIO_Speed_50MHz;
	mGPIO.GPIO_Pin = GPIO_Pin_8;
	GPIO_Init(GPIOA, &mGPIO);
	mGPIO.GPIO_Pin = GPIO_Pin_9;
	GPIO_Init(GPIOC, &mGPIO);
	
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_I2C3);
	GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_I2C3);
	

	I2C_InitTypeDef mI2C;
	
	mI2C.I2C_Ack = I2C_Ack_Enable;
	mI2C.I2C_ClockSpeed = 100000;
	mI2C.I2C_DutyCycle = I2C_DutyCycle_2;
	mI2C.I2C_Mode = I2C_Mode_I2C;
  mI2C.I2C_OwnAddress1 = 0x00;
  mI2C.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	
	I2C_Init(I2C3, &mI2C);
	I2C_Cmd(I2C3, ENABLE);


Buda veri göndermeye çalışan ancak başarılı olamayan send fonksyionu
i2c_enable_ack();
	I2Cx->OAR1 = (DevID << 1);
	
	//Send Start Condition
	i2c_start_condition();
	while(!(i2c_event_control(0x30001)));		//BUSY, MSL, SB
	
	//Send Address of Slave Device
	I2Cx->DR = (DevID << 1);
	while(!(i2c_event_control(0x70080)));	//TRA, BUSY, MSL, TXE
	
	//Send Data LSB first
	while(n)
	{
		I2Cx->DR = data[0];
		while(!(i2c_event_control(0x70080)));
		data++; n--;
	}
	while(!(i2c_event_control(0x70084)));	//TRA, BUSY, MSL, TXE, BSF
	i2c_stop_condition();


Yukarıdaki koda geldiğinde BUSY biti 1 durumunda. i2c_start_condition'dan sonra gelen ilk while'da program tıkanıyor. Ancak dediğim gibi eğer voltajı çekip tekrar verirsem aynı kod parçası hatasız çalışıyor. Sorun reset attığımda bir daha çalışmaması

z

I2C nin register anlatimlarinda bu duruma atifta bulunulmuş.

Donanimi, dustugu kuyudan cikarmaya yarayan bir bit var. Dun bakarken gozume ilisti.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

CLR

stm32f103 serisinde I2C modülü ilk önce enable edilmeli sonra  register'ları ayarlanmalıydı, F429'da da aynı sorun varmı bilmiyorum ama muhtemelen vardır. Programında baktım registerlerden sonra enable etmişsin. Aşağıdaki gibi bir dene. Ayrıca STM32'nin I2C modülü en iyi interrupt veya dma ile iyi çalışıyor, zaten en mantıklısıda bu değil mi? 160Mhz'lik işlemci gereksiz bit beklemeleri ile çalışması I2C frekansına düşüyor. Bu durumda 160Mhz kullanmanın bir esprisi olmaz. DMA ile kullan en iyisi bu. Veri transferleri bittiğinde DMA full transfer interrupt ile işlemin bittiğini anlarsın sonraki işlemlerini gerçekleştirirsin. Hemde işlemci boşta kalır.

I2C_Cmd(I2C3, ENABLE);
I2C_Init(I2C3, &mI2C);
Knowledge and Experience are Power