Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

stm32 i2c yardım

Başlatan Gökhan BEKEN, 05 Ağustos 2014, 15:10:41

Gökhan BEKEN

Merhaba,
i2c protokolü ile ilk defa çalışıyorum, i2c protokolünün alt yapısını araştırdım microchip'in dökümanlarından ve yabancı videolardan felan öğrendim(sanırım). Stm32 için hazırlanmış örneklere bakarak birşeyler yaptım ama istediğim sonucu alamıyorum.
(bu projede stm32f4 discovery kullanıyorum)

Maddeler halinde sorayım...
1-Baktığım örneklerin çoğu i2c kanalı olarak i2c2 yi kullanarak, SCL pinini pb10 , SDA pinini pb11 olarak olarak seçmiş. Ancak böyle olunca hiç tepki alamıyorum. Ben i2c kanalı olarak i2c1, SCL pinini pb7 , SDA pinini pb8 olarak seçince tepki alabiliyorum. Neden böyle olur?

2- Aşağıdaki şekilde görüleceği üzere alttaki mavi sinyal SCL sinyalim, üstteki sarı sinyal ise SDA sinyalim. Bu sinyaller oldukça tutarsız değil mi?


kullandığım kodlar:


  
  //init bolumu://///////////////////////////////////
  I2C_InitTypeDef  I2C_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure I2C1 pins: SCL and SDA */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7 | GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_Init(GPIOB, &GPIO_InitStructure);


  /* Enable I2C and GPIO clocks */
  RCC_APB1PeriphClockCmd(I2C1_RCC_Periph, ENABLE);
  RCC_AHB1PeriphClockCmd(I2C1_RCC_Port, ENABLE);
  /* Configure I2C pins: SCL and SDA */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7 | GPIO_Pin_8; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType=GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
  GPIO_Init(I2C1_Port, &GPIO_InitStructure); 
      
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);

  I2C_DeInit(I2C1);

  /* I2C configuration */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = 0x68; // cihazın i2c adresi
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = I2C1_Speed;

  /* Apply I2C configuration after enabling it */
  I2C_Init(I2C1, &I2C_InitStructure);
  /* I2C Peripheral Enable */  
  I2C_Cmd(I2C1, ENABLE);
  
  ///////////////////////////////////////////

  
  //veri gonderme bolumu:
  I2C_GenerateSTART(I2C1, ENABLE);
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  while(1){
  	I2C1->DR = 0x1F;
  }


3- Bu satırın ne işe yaradığını test ettim, sonuç olarak pinlerden high okuyana kadar bekliyor:
while(!I2C_CheckEvent(MPU9150_I2C, I2C_EVENT_MASTER_MODE_SELECT));

Pinler boştayken high'a çektiğimde while'den çıkıyor. Bu komutun amacı nedir?
4- i2c ile bir slave cihazın, bir registerindeki değerini okumak için en basitinden ne yapabilirim?

5- start bitinden sonra, veri göndermek istediğim cihazın adresini gönderirken, 1 bit sola kaydırmama gerek var mı, stm32 donanımı bunu kendi yapıyor mu? Sorma sebebim şu: normalde en sağdaki bit(LSB) W/R (okuma/yazma) belirteci olduğundan 7 bitlik adresin sonuna ekleniyor. Bunu ben kendim mi yapıyorum yoksa stm mi yapacak?
Özel mesaj okumuyorum, lütfen göndermeyin.

muuzoo

Bir yanlışlık var sanırım, üstteki sinyal SCL alttaki ise SDA olmalı.
gunluk.muuzoo.gen.tr - Kişisel karalamalarım...

yldzelektronik

2- Yanlışın olmasın?Tam tersi gibi geldi bna?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Gökhan BEKEN

Bana da öyle geliyor ama kontrol ettim doğru pinler.
pb7 pini SCL olarak ayarlı ve ekrandaki mavi sinyali alıyorum. Yazılımda bir yerde terslik var galiba.  Başka gereksiz şeyler olduğu için sadece önemli kısmı vermiştim. Normalde yazdığım kodların tamamı şöyle:

main.c:

#include "main.h"


int main(void)
{
	SystemInit();
	
	SysTick_Config(SystemCoreClock / 1000); //1milisaniyelik system clock elde edelim
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); // 	RCC->AHBENR |= RCC_AHBENR_GPIODEN ; //GPIO D clock'u aktif edelim
  
	init_usart();
		
	USART_puts(USART2,"start\r\n");
	
	MPU6050_I2C_Init();	
	
	I2C_GenerateSTART(MPU9150_I2C, ENABLE);
	Timed(!I2C_CheckEvent(MPU9150_I2C, I2C_EVENT_MASTER_MODE_SELECT));	

while(1){
	MPU9150_I2C->DR = 0x1F;
}


	errReturn:
	USART_puts(USART2,"hata aldik \r\n");
	while (1) {
		GPIOD->ODR|=(1<<12);
		MyDelay=1000; while(MyDelay);
		GPIOD->ODR&=~(1<<12);
		MyDelay=1000; while(MyDelay);
	}	

}


main.h :
#include "stm32f4xx.h" 
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h> //reset and clock config
#include <stm32f4xx_usart.h>
#include <stm32f4xx_i2c.h>
#include <system_stm32f4xx.h>
#include <stdio.h>

uint32_t Timeout = 0;
#define Timed(x) Timeout = 0xFFFF; while (x) { if (Timeout-- == 0) goto errReturn;}


#define MPU9150_I2C                  I2C1
//#define MPU9150_I2C                  I2C2
#define MPU9150_I2C_RCC_Periph       RCC_APB1Periph_I2C1
// #define MPU9150_I2C_RCC_Periph       RCC_APB1Periph_I2C2
#define MPU9150_I2C_Port             GPIOB

#define MPU9150_I2C_SCL_Pin          GPIO_Pin_7
#define MPU9150_I2C_SDA_Pin          GPIO_Pin_8
// #define MPU9150_I2C_SCL_Pin          GPIO_Pin_10
// #define MPU9150_I2C_SDA_Pin          GPIO_Pin_11

#define MPU9150_I2C_RCC_Port         RCC_AHB1Periph_GPIOB
#define MPU9150_I2C_Speed            100000 // 100kHz standard mode

#define MPU9150_ADDRESS_AD0_LOW     0x68 // address pin low (GND), default for InvenSense evaluation board
#define MPU9150_ADDRESS_AD0_HIGH    0x69 // address pin high (VCC)
#define MPU9150_DEFAULT_ADDRESS     (MPU9150_ADDRESS_AD0_LOW<<1)


/* Private typedef -----------------------------------------------------------*/
GPIO_InitTypeDef  GPIO_InitStructure;


volatile short MyDelay;
void USART_puts(USART_TypeDef* USARTx,  char *s);
void init_usart(void);


void MPU6050_I2C_Init(void);

void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead);


u8 Rx_Buffer[16];

void SysTick_Handler(void) {
	if(MyDelay) MyDelay--;
}



void USART_puts(USART_TypeDef* USARTx, char *s){

	while(*s){
		// wait until data register is empty
		while( !(USARTx->SR & 0x00000040) );
		USART_SendData(USARTx, *s);
		*s++;
	}
}


void init_usart(void){

	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	/* enable peripheral clock for USART2 */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);


	/* GPIOA clock enable */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

	/* GPIOA Configuration:  USART2 TX on PA2 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* Connect USART2 pins to AF2 */
	// TX = PA2
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);

	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx;
	USART_Init(USART2, &USART_InitStructure);

	USART_Cmd(USART2, ENABLE); // enable USART2

}




void MPU6050_I2C_Init(void)
{
  I2C_InitTypeDef  I2C_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable I2C and GPIO clocks */
  RCC_APB1PeriphClockCmd(MPU9150_I2C_RCC_Periph, ENABLE);
  RCC_AHB1PeriphClockCmd(MPU9150_I2C_RCC_Port, ENABLE);
  /* Configure I2C pins: SCL and SDA */
  GPIO_InitStructure.GPIO_Pin =  MPU9150_I2C_SCL_Pin | MPU9150_I2C_SDA_Pin; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType=GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
  GPIO_Init(MPU9150_I2C_Port, &GPIO_InitStructure); 
      
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);

  I2C_DeInit(MPU9150_I2C);

  /* I2C configuration */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = MPU9150_DEFAULT_ADDRESS; // MPU6050 7-bit adress = 0x68, 8-bit adress = 0xD0; 
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = MPU9150_I2C_Speed;

  /* Apply I2C configuration after enabling it */
  I2C_Init(MPU9150_I2C, &I2C_InitStructure);
  /* I2C Peripheral Enable */  
  I2C_Cmd(MPU9150_I2C, ENABLE);

}







Özel mesaj okumuyorum, lütfen göndermeyin.

muhittin_kaplan

#4
hocam kolay gelsin,
bloğa da yazmışsın ama bir türlü cevap veremedim durumum malum.

aynı hatayla bende karşılaşmıştım. devamlı döngüde kalıyordu.
pek hatırlamıyorum ama sanki çalışma hızıyla alakalı bir problemdi.

mesaj birleştirme:: 06 Ağustos 2014, 13:58:56

adresleri kontrol et meftun

Alıntı YapI was testing my I2C code, It took too much time. Unfortunately It was very hard to figure out what was happening to my I2C code written for MPU6050 with the old oscilloscope i'm using could not help me to solve. After posting my problem in ST Forum, a few people suggested after days. Meanwhile i started testing my MPU6050 breakout board from Sparkfun on Arduino pro mini. Initially it didn't work. I communicated with Jeff( a nice guy). I desoldered & soldered the connections, checked for continuity, voltage levels etc. It worked finally. So, now after making sure I'm back onto my Olimex STM32-P103 board to test I2C code. No luck.  After digging out, I fixed it. It was the 7-bit address problem. MPU6050 I2C address is 0x68. But in STM32, i have to use the 1-bit left shifted address(0xD0) of this.

mesaj birleştirme:: 06 Ağustos 2014, 13:59:58

http://harinadha.wordpress.com/2012/05/22/mpu6050-dev-stm32/

arm-beginner

Errata Sheet'e bir göz attınmı? STM32F1xx kadar olmasada, STM32F4 'ün de birkaç cansıkıcı hataları var.
Ayrıca senin kod ile herhangi bir entegre ile iletişime girmen mümkün değil. Çok fazla eksiklerin var.
Ama sadece "concept of proof" için kullanıyorum diyorsan, diyecem birşey yok.

Sana tavsiyem: ST'nin yayınladığı I2C kütüphaneler ve örnekler ile hiç uğraşma. Ben eninde sonunda DMA ile haberleşmeyi başardım. Ama orda ağıçlar yüzünden ormanı göremez hale geldiğim için, taaaa Z80 zamanlarında yazdığım I2C prosedürleri STM32'ye adapte ettim.

Ama ilaki onları kullanmak istiyorsan: AN2824 isimli application note ve onun kodları bana epey yardımcı olmuşdu.

Benim şahsi düşüncem: I2C ile kaç byte transfer ediyoruz? Ben I2C entegreler ile haberleşdiğim zaman, taş çatlasın 4 byte ya gidiyor, ya geliyor. Bunun için ne interrupt, ne DMA 'ya gerek var.

Gökhan BEKEN

@arm-beginner hocam sizin kütüphaneniz yazılımsal çalışıyor sanırım. Aslında böyle işleri donanıma yaptırmak yerine böyle bir kez yazılımsal kütüphane yazıp her platformda kullanmak daha mantıklı. Kütüphanenizi paylaşırsanız faydalanırız.
Bu arada  st'nin dökümanlarına bakmadım hiç, bahsettiğiniz dökümanları inceleyeceğim.
Özel mesaj okumuyorum, lütfen göndermeyin.

CLR

Arkadaşlar,

I2C  sıkıntılı bir haberleşme çeşitidir, karşıdan ACK gelmezse while'dan çıkabilicek şekilde kod yazmanız lazım, yoksa hiç sağlıklı bir proje olmaz, çok sıkıntılar yaşarsınız. Onun için kontrolü donanıma yıkın, hem siz, hemde işlemci rahatlasın, I2C için DMA ve I2C interrupt haricinde haberleşme kullanmayın. Zaten ST'de bunu öneriyor.

Mesela DMA ile I2C haberleşmeyi öğrenin (Tonla örnek var), dma'yı tüm registerleri okuduktan sonra interrupt'ta girecek şekilde kurarsanız(full complete interrupt), ve sonra systemtick timer ile Xms'de(10ms,100ms olur vs) DMA'yı tetikleyin oda size kaç register okumak istiyorsanız, 3-5-7-10 registerin hepsini periyodik Xms'de bir okusun.

STM32F4 kullanıp, soft I2C kullanıyorum derseniz size gülerler.
Knowledge and Experience are Power

arm-beginner

@CLR
Elbette gülebilirsiniz.Ve elbette bilmediğim birşey var ise, öğrenmeye herzaman hazırım.
Merak ettiğim 2 konu var.
- Bir Eeprom'a yazarken, DMA ile page-boundary kontrolü nasıl yapıyorsunuz?
- Varsayalım i2c slave cevap vermiyor. DMA ile bus-recovery nasıl yapıyorsunuz?

CLR

Alıntı yapılan: arm-beginner - 08 Ağustos 2014, 09:51:12
@CLR
Elbette gülebilirsiniz.Ve elbette bilmediğim birşey var ise, öğrenmeye herzaman hazırım.
Merak ettiğim 2 konu var.
- Bir Eeprom'a yazarken, DMA ile page-boundary kontrolü nasıl yapıyorsunuz?
- Varsayalım i2c slave cevap vermiyor. DMA ile bus-recovery nasıl yapıyorsunuz?


Arm-beginner,

Gülerim demedim, "gülerler" dedim. Zaten bir elektronikçi herzaman öğrenme modunda olmalı, ben proje aldığım zaman, geçmişte aynı projeyi yapmış bile olsam, yeni şeyler öğreneyim diye hep farklı yoldan yapmaya çalışırım ki, ancak kendini zorlarsan yeni şeyler öğrenebiliriz.

Sorularına gelince,

1) Bu soru biraz gereksiz olmuş, Page'in DMA/interrupt ile alakası yok.dma'ya nekadar yazarsan o kadar data basar veya alır. Page kontrol edeceksen ki (ben hiç etmem, tüm yazacaklarımı bir tabloda turarım yeri geldiğinde(timing) yazılır veya okunur) bunu mecburi soft yapmalısın. Büyük datalar yazacaksan okuyacaksan, page'lere bölebilirsin ve dma ile page page yazabilirsin.

2) DMA'da ack gelmezse veya başka bir sorunda okuma/yazma gerçekleşmez ama timeout bitince yeni data geldi flag'in set değilse veya dma full transfer interrupt set olmamışsa, I2C hatta bir sorun olabilir, IC bozulabilir, pull-uplar olmayabilir vs bu durumda işlemci kitlenmez sadece dma haberleşmeyi tamamlayamaz ve dma error flag set olur ve ilgili dma kanalı otomatikman disable olur. Sonra tekrar enable edip flagleri silip tekrar kullanabilirsin. 

Sorularını açıkladım, bu defa  ben sorayım sen cevapla.

168MHz'lik işlemcide I2C 100Khz'lik hatta bir page yani 256byte soft data transferi için gereken süre nekadardır? Ve bu işlemi 50ms'de bir periyodik yapmamız gerekiyorsa, bu hesapladığın süre veya I2C haberleşmesi süresi işlemcinin %x 'lik işlem hacmini kullanıyor? Daha başka değişle % kaç 100Khz'de %kaç 168Mhz'de çalışıyor? (page yazmak için gereken bekleme süresini yoksay veya hw yaptığını varsay, yani sadece işlem süresi hesaplanacak)
Knowledge and Experience are Power

arm-beginner

İlk sorum gereksiz olduğunu düşünmiyorum. Tabii ki page-boundry kontrolü DMA ile bir alakası yok. Ama yazarken ben bunu orda kontrol etmem lazım - çünkü yanlış hatırlamiyorsam, DMA'da tek bir BYTE yazdıramiyorum. Mutlaka bir WORD olmak zorunda.
---
2. soruma gelince, cevabın sorum ile bir alakası yokmuş gibi geldi bana. "Sonra tekrar enable edip flagleri silip tekrar kullanabilirsin."
Güzelde, slave entegrenin i2c interface'i kilitlenmiş. İsdediğin kadar tekrarla :)
Burda 3 seçenek var:
- cihazı komple kapatıp açmak
- slave entegrenin reset pini var ise (ve o MCU'ya bağlı ise) reset atmak
- veya yazılım ile reset atmaya çalışırsın (Analog Device AN-686  http://www.analog.com/static/imported-files/application_notes/54305147357414AN686_0.pdf )
İşde bunu DMA ile nasıl yapıyorsun, onu merak etmişdim.


Soruna gelince:
İlkönce benim şahsen (seni tabii bilemem) I2C arayüzü ile bağli olan entegreler ile yoğun bir haberleşmem hiç olmadı. Ve öyle olabilecek bir szenaryo aklımada gelmiyor.
I2C eskiden daha çok kullanırdım. Şimdi kaldı kaldı sadece eeprom'lar. Ama ordada: cihaz açıldığında eeprom'da kayıtlı flash'in hash değerini kontrol ederim, bazı parametreleri okurum ve kullanıcı gerekirse setup'a girerek bazı parametreleri değiştirir. Burda belki toplamda 20 - 30 bytes söz konusu, ama bunlar belki 20 farklı adımlarla okunuyor veya yazılıyor.
Elbette yüksek miktarlı veriler depoluyorum. Ama onları  SPI ile DataFlash'a yazıyorum.

Neydi sorun? "168MHz'lik işlemcide I2C 100Khz'lik hatta bir page yani 256byte soft data transferi için gereken süre nekadardır?"
Bir page 256 byte olmak zorunda değil. Şu an kullandığım Eeprom'un page boyutu 8 byte. Başka bir board'da 32 byte. Şu an STM32F103 ile çalışıyorum, ve bu nedenle sadece onun ile ilgili bir değer verebilirim:

STM32F103 @72MHz / Eeprom 24AA01 (128 Bytes / Page 8 Bytes)

8 Byte : 1.8ms   (1)
8 Byte : 6.5ms   (2)


(1) Adres 0x00, böylece page boundary kontrolü devreye girmiyor ve eeprom yazma işlemin bitmesi beklenmiyor
(2) Adres 0x01, böylece page boundary kontrolü devreye giriyor ve 7 byte yazılmasını bekliyor

Yukardaki değerler 10 katı olsa, hadi diyelim 100 katı: ne yazar? Cihaz açılırken 180ms geç açılmış. Eee? Bana ne. Müşteri paramatreyi değiştirdiğinde 10us yerine 1ms beklemiş. Bu şikayet konusu olursa, elbette parasını iade ederim.
Burda ama şöyle bir avantajım var: kodları ben yazdım ve karşımda bir black-box yok. Ve ST'nin Errata Sheet'in de yayınladığı Workaround'lar umrumda değil.

Ama bu tabii bir tercih meselesi.

CLR

Kardeş sen bildiğin gibi yap. Aynı konulardan bahsetmiyoruz.

stm32F103'e soft reset için aşağıdaki tanımlamayı kullanabilirsin
#define SoftReset()     SCB->AIRCR=0X05FA0700|(u32)0x04;
Knowledge and Experience are Power

arm-beginner

Alıntı yapılan: CLR - 08 Ağustos 2014, 19:52:48
Kardeş sen bildiğin gibi yap. Aynı konulardan bahsetmiyoruz.

stm32F103'e soft reset için aşağıdaki tanımlamayı kullanabilirsin
#define SoftReset()     SCB->AIRCR=0X05FA0700|(u32)0x04;

Evet, farklı şeylerden bahsediyoruz. Ben sana i2c iletişim hatını nasıl reset'liyorsun diye soruyorum, ve sen STM32 resetlemekden bahsediyorsun.

CLR

Alıntı yapılan: arm-beginner - 08 Ağustos 2014, 18:27:05
2. soruma gelince, cevabın sorum ile bir alakası yokmuş gibi geldi bana. "Sonra tekrar enable edip flagleri silip tekrar kullanabilirsin."
Güzelde, slave entegrenin i2c interface'i kilitlenmiş. İsdediğin kadar tekrarla :)
Burda 3 seçenek var:
- cihazı komple kapatıp açmak
- slave entegrenin reset pini var ise (ve o MCU'ya bağlı ise) reset atmak
- veya yazılım ile reset atmaya çalışırsın

@Arm-beginner,

Hatalarını gördüğüm için ve bunları yazmak zamanımı alacağın için ve büyük ihtimalle senin herşeyi açık yazsamda konuyu uzatacağını bildiğim için, kısa kesmek istedim ama hem konuyu detaylı bilmeyip hemde laf sokmaya çalışıyorsun ya bu nedenle belki öğretici olur diye cevap yazmak istedim.

"I2C arayüzü ile bağli olan entegreler ile yoğun bir haberleşmem hiç olmadı" diyorsun ya haklısın çünkü bir ACK sinyali low voltage level'e sahiptir. I2C hatları ise idle'da high'da bekler, I2C hattına çok sayıda I2C IC bağlayabilirsin. Bunu neden yazdı diye belki ilk okumada anlamamış olabilirsin,  aşağıdakileri okuyunca anlayacaksın.

Ayrıca yazdıklarımı iyi okursan işlemci resetlenmez, sadece dma kanalı disable olur, onuda istersen tekrar açabilirsin yani bırak işlemciyi o dma kanalı bile kitlenmez dedim sen ise I2C hatı kitlendi tekrar açıp neyapacaksın diyorsun ve pişkin pişkin gülücük koymuşsun.  Tane tane yazayım, ACK sinyali logic 0 seviyesine sahiptir, yani gelmezse hat kitlenmez.

İlgili entegre ack göndermezse hattı low'a çekmemiş demektir bu gürültülerden, arızalardan vs. kaynaklanabilir, birkereye mahsusda olabilir, high'da bekleyen I2C hatları kullanılabilir durumdadır, o low'a çekemiyorsa hatta bağlı olan başka IC'ler le haberleşmek istenebilir. I2C ile sadece eepromlarla haberleşilmiyor, bir çok IO expander, dac,adc, analog switchler, sensörler vs. var. 

İlgili IC'de sorun varsa dma kanalı tekrar kullanılabildiği için tekrar deneyip emin olabilirsin veya kritik bir arıza değilse diğerleri ile haberleşebilirsin, kritik bir arıza ise kullanıcıya hatayı bildirebilirsin. Ve arıza onarılıncaya kadar kartı kullanıma kapatabilirsin vs. vs.

STM32 soft reset kodunu ise, yukarıda alıntı yaptığım 3 seçeneğin için yazdım, bana lazım olduğu için değil sana lazım olduğu için, Çünkü soft I2C haberleşmede timeout koyulmazsa işlemci kitlenebilir. Bunu ilk mesajımda yazmıştım zaten. Yoksa soruna cevap olsun diye yazmadım. Yani promosyon olarak yazdım, gereksiz bilgi olarakta görebilirsin.

Ayrıca konuyu kısa kesmemin diğer sebebi, Sen soruma kaçamak cevap verdin, benim soruma değil kendi istediğin gibi soru oluşturdun ve kendi kullandığın gibi açıklıyorsun.

I2C hattında kullanılan IC'lerle sadece ilk açılışta haberleşilmiyor, periyodik olarakta haberleşiliyor. Dolayısıyla periyodik olarak haberleşme süresi işlemci kullanılabilirliğini etkiliyor. Bu nedenle kullanıcı 1ms veya 100ms beklemiş sorun olmaz demekle olmaz.

Senin verdiğin örnekte bile 6,5ms ile işlemcinin %13'ünü sadece 100Khz'lik IC kapatıyor, 256byte için işlemcinin minimum %50'sini kaplar.

Sonuç olarak sen işlemcinin %13 ile sadece 100Khz'lik bir I2C ile haberleşirken ben o süreyi hem senin yapacağın işlemi hemde başka şeyler için kullanırım mesela dma'nın I2C kanalı ile, hem senin yapacağın işlemi yaptırırım hemde paralel olarak, aynı zaman diliminde 4-5 tane ADC kanalını dma ile okuyup, hepsinin true rms hesabını yaparım.
Aradaki fark bu işte.   
Knowledge and Experience are Power

Karamel

hocam araya girip birsey sormak ve hemen sivismak istiyorum :) belirli kodlarin islemcinin %kac islem gucunu kapsadigini nasil hesapliyoruz? bu hesabi nasil yapabilirim?