EEPROM 24c256 ve stm32

Başlatan muhittin_kaplan, 31 Aralık 2013, 19:44:11

muhittin_kaplan

i2c ile iletişimi kontrol edbiliyorum, ne gönderdim ne aldım lojik analizörle bakıyorum.

24c256 ya yazmak ve okumak için neler yapmalıyım.

(buraya kadar gelen hastanın hikayesini anlatayım. Epromla alakalı birkaç kütüphane denedim, hiçbirinde muvaffak olamadım. bir adım geri döndüm, önce i2c ile denemeler yaptım problem yoktu. eprom la çalışmaya başladığımda bazı hatalar buldum düzelttim.  incelediğimde   epromun datasının (syf11) sırasıyla config byte,adresH adresL ve data göndermem gerektiğini aralarda ACK ve sonuçta Nack ile bitirmemi söylüyor. Okurkende buna benze yapıyla kurmamı söylüyor, yazma ile okuma arasında fark configdeki son bitin 1 yapılması. Ama ne yaptımsa olmadı..)

magnetron

http://application-notes.digchip.com/023/23-19860.pdf

hocam burda 8051 ile yapılmış örnek var
çok eski ama , belki bir fikir verir

muhittin_kaplan

#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_i2c.h"

#define I2C_TIMEOUT_MAX 		100000
#define Mem_Type 				M24256
#define MEM_DEVICE_WRITE_ADDR 	0xA0
#define MEM_DEVICE_READ_ADDR	0xA1
void init_I2C1(void){

	GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as I2C1SDA and I2C1SCL
	GPIO_InitTypeDef GPIO_Output;     // For some debugging LEDs
	I2C_InitTypeDef I2C_InitStruct; // this is for the I2C1 initilization

	/* enable APB1 peripheral clock for I2C1*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

	/* enable the peripheral clock for the pins used by
	 PB6 for I2C SCL and PB9 for I2C1_SDL*/
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

	/* This sequence sets up the I2C1SDA and I2C1SCL pins
	 * so they work correctly with the I2C1 peripheral
	 */
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_9; // Pins 6(I2C1_SCL) and 9(I2C1_SDA)
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // the pins are configured as alternate function so the USART peripheral has access to them
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;// this defines the IO speed and has nothing to do with the baudrate!
	GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;// this defines the output type as open drain
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;// this activates the pullup resistors on the IO pins
	GPIO_Init(GPIOB,&GPIO_InitStruct);// now all the values are passed to the GPIO_Init()

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

	 /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */
        GPIO_Output.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
        GPIO_Output.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_Output.GPIO_OType = GPIO_OType_PP;
        GPIO_Output.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_Output.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOD,&GPIO_Output);

	/* The I2C1_SCL and I2C1_SDA pins are now connected to their AF
	 * so that the I2C1 can take over control of the
	 * pins
	 */
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); //
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);

	 /* Configure I2C1 */
        I2C_DeInit(I2C1);

        /* Enable the I2C peripheral */
        I2C_Cmd(I2C1, ENABLE);

        /* Set the I2C structure parameters */
        I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
        I2C_InitStruct.I2C_OwnAddress1 = 0xEE;
        I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
        I2C_InitStruct.I2C_ClockSpeed = 30000;

        /* Initialize the I2C peripheral w/ selected parameters */
        I2C_Init(I2C1,&I2C_InitStruct);
}

uint8_t Write_24Cxx(uint16_t Addr, uint8_t Data, uint8_t Mem_Type)
{

	uint32_t timeout = I2C_TIMEOUT_MAX;
	uint8_t upper_addr,lower_addr;

	lower_addr = (uint8_t)((0x00FF),Addr);

	if(Mem_Type==M24512)
	{
	Addr = Addr>>8;
	upper_addr = (uint8_t)((0x00FF)&Addr);
        }
       /* Generate the Start Condition */
       I2C_GenerateSTART(I2C1, ENABLE);

       /* Test on I2C1 EV5, Start trnsmitted successfully and clear it */
       timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
       while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
       {
            /* If the timeout delay is exeeded, exit with error code */
		if ((timeout--) == 0) return 0xFF;
       }

       /* Send Memory device slave Address for write */
       I2C_Send7bitAddress(I2C1, MEM_DEVICE_WRITE_ADDR, I2C_Direction_Transmitter);

       /* Test on I2C1 EV6 and clear it */
       timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
       while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
       {
           /* If the timeout delay is exeeded, exit with error code */
		if ((timeout--) == 0) return 0xFF;
       }

	if(Mem_Type==M24512)
	{
		/* Send I2C1 location address LSB */
		I2C_SendData(I2C1, upper_addr);

		/* Test on I2C1 EV8 and clear it */
		timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
		while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
		{
			/* If the timeout delay is exeeded, exit with error code */
			if ((timeout--) == 0) return 0xFF;
		}
	}
	/* Send I2C1 location address LSB */
        I2C_SendData(I2C1, lower_addr);

      /* Test on I2C1 EV8 and clear it */
      timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
      while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
      {
            /* If the timeout delay is exeeded, exit with error code */
		if ((timeout--) == 0) return 0xFF;
      }

       /* Send Data */
       I2C_SendData(I2C1, Data);

        /* Test on I2C1 EV8 and clear it */
        timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        {
             /* If the timeout delay is exeeded, exit with error code */
		if ((timeout--) == 0) return 0xFF;
        }

        /* Send I2C1 STOP Condition */
        I2C_GenerateSTOP(I2C1, ENABLE);

        /* If operation is OK, return 0 */
        return 0;
}

uint8_t Read_24Cxx(uint16_t Addr, uint8_t Mem_Type)
{
  uint32_t timeout = I2C_TIMEOUT_MAX;
  uint8_t Data = 0;

  uint8_t upper_addr,lower_addr;

  lower_addr = (uint8_t)((0x00FF)&Addr);

	if(Mem_Type==M24512)
	{
		Addr = Addr>>8;
		upper_addr = (uint8_t)((0x00FF)&Addr);
	}
  /* Generate the Start Condition */
  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on I2C1 EV5 and clear it */
  timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
  {
    /* If the timeout delay is exceeded, exit with error code */
		if ((timeout--) == 0) return 0xFF;
  }

  I2C_Send7bitAddress(I2C1, MEM_DEVICE_WRITE_ADDR, I2C_Direction_Transmitter);

  /* Test on I2C1 EV6 and clear it */
  timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    /* If the timeout delay is exeeded, exit with error code */
		if ((timeout--) == 0) return 0xFF;
  }

	if(Mem_Type==M24512)
	{
		/* Send I2C1 location address LSB */
		I2C_SendData(I2C1,upper_addr);

		/* Test on I2C1 EV8 and clear it */
		timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
		while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
		{
			/* If the timeout delay is exeeded, exit with error code */
			if ((timeout--) == 0) return 0xFF;
		}
	}

	  /* Send I2C1 location address LSB */
          I2C_SendData(I2C1, lower_addr);

          /* Test on I2C1 EV8 and clear it */
          timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
          {
               /* If the timeout delay is exeeded, exit with error code */
		if ((timeout--) == 0) return 0xFF;
          }

          /* Clear AF flag if arised */
          //I2C1->SR1 |= (uint16_t)0x0400;

          /* Generate the Start Condition */
          I2C_GenerateSTART(I2C1, ENABLE);

          /* Test on I2C1 EV6 and clear it */
          timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
          {
               /* If the timeout delay is exeeded, exit with error code */
		if ((timeout--) == 0) return 0xFF;
          }

          I2C_Send7bitAddress(I2C1, MEM_DEVICE_READ_ADDR, I2C_Direction_Receiver);

          /* Test on I2C1 EV6 and clear it */
          timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
          {
                /* If the timeout delay is exeeded, exit with error code */
		if ((timeout--) == 0) return 0xFF;
          }

          /* Prepare an NACK for the next data received */
          I2C_AcknowledgeConfig(I2C1, DISABLE);

          /* Test on I2C1 EV7 and clear it */
          timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
          {
                /* If the timeout delay is exeeded, exit with error code */
                 if ((timeout--) == 0) return 0xFF;
          }

          I2C_GenerateSTOP(I2C1, ENABLE);

          /* Receive the Data */
          Data = I2C_ReceiveData(I2C1);

          /* return the read data */
          return Data;
}

int main(void)
     {
  	int i;
        init_I2C1(); // initialize I2C1
	if(Write_24Cxx(0x0000,0x11,24512))
	{
		//error
		while(1);
	}

	if((Read_24Cxx(0x0000,24256))==0x55)
	{      // ERROR
		while(1)
		{
		    GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
			GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
			GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
			//Delay(0x05ffffff);
		}
	}
	else if((Read_24Cxx(0x0000,24256))==0x55)
	{

		//Success
	}

        while (1)
        {

		        // Comes here in the end....
			GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
			//Delay(0x005fffff);
        }
    }

muhittin_kaplan

Kendim çalıp Kendim oynuyorum.

Yukarda verdiğim kod çalışıyor.
Hızdan dolayı Yazmama yazamama gibi durumlar olabilirmi, iki yazma arası bekleme koymalımıyım ?
datasında Twr den basetmiş ve max 10ms (or 2^5) demiş

muhittin_kaplan

Bu EEProm WP 0 damı koruyor

yaptığım denemelerde 0 da koruyor ibibik.

Alıntı YapWRITE PROTECT (WP): The write protect input, when connected to GND, allows normal write
operations. When WP is connected high to VCC, all write operations to the memory are inhibited. If the pin is left floating, the WP pin will be internally pulled down to GND if the capacitive
coupling to the circuit board VCC plane is <3 pF. If coupling is >3 pF, Atmel recommends connecting the pin to GND.

Mucit23

Yok hocam 1 de koruyor olması gerek

Bayramsumbul

Hocam merhaba.Debug yaptınız mı.?Debug yapar iken sadece kod değil,doğrudan yazmaçlarada değer verilebiliyor.
Ben programı sonsuz döngüye sokup,Debug yapıyorum.O sırada yazmaçlar ile oynayarak mesela uart'ı deniyorum..
Bir Elektronik Meraklısının Serüveni...

muhittin_kaplan

Lojik analizorle iic analizi yapiyorum

muhittin_kaplan

pin i kopukmuş şerefsiz kablonun,


M_B

muhittin_kaplan Hocam;
Hocam size LM75 entegresi göndereyim mi ?
Şu yönden dedim. Benim bununla ilgili Stm32f407 de calışan kodum var.
Hem kodları kontrol eder hemde entegreyi çalıştırır denersiniz.

Not: Hocam isterseniz 24C02 ile calışmaya devam edin. Once bunu calıştırın sonra 24c256 ya gecersiniz.
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

muhittin_kaplan

#10
Hacam Eksik Olmayın, EEPROM şu an çalışıyor Sıkıntı Kalmadı.

mesaj birleştirme:: 04 Ocak 2014, 16:29:42

Soru Arada Kalmış Sanırım

iki Byte yazma arası bekleme koymalı mıyım ?
(Şu an kitabında söylediği ve denemelerim sonucu 2ms altına inerse yazamıyor.)

mesaj birleştirme:: 04 Ocak 2014, 16:31:55

birde Max Clock Speed Ne olmalı

I2C_InitStruct.I2C_ClockSpeed = 30000;

mistek

#11
Alıntı yapılan: muhittin_kaplan - 04 Ocak 2014, 16:18:57
birde Max Clock Speed Ne olmalı

I2C_InitStruct.I2C_ClockSpeed = 30000;

Hocam kullandığınız entegreye göre hızı ayarlayabilirsiniz Fast Mode destekliyorsa max 400KHz. Ultra Fast ise 1MHz. Her ikiside değilse 100KHz veya aşağısı.


Datasheet ilk sayfada DEVICE SELECTION TABLE var.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

fatih6761

#12
Hocam bir de Byte Write ve Page Write olayı var. Yanlış hatırlamıyorsam 128 bayta kadar sıralı yazma yapabiliyorsunuz. Modüle device address gönderdikten sonra bir adres veriyorsunuz(sizin durumunuzda iki bayt adres olacak). Bundan sonra sırayla en fazla 128'e kadar bütün baytları yolluyorsunuz. Tam emin olmak için datasheet'e bakabilirsiniz.

Önemli Edit:
Burada şöyle bir sıkıntı varmış: Bir page write işleminde yalnızca bir page'e yazabiliyormuşuz. Yani sıralı yazma işlemi aşağıdaki gibi aralıklarda olmalı...
0 - 63
64 - 127
128 - 191
192 - 255
...



Mesela Arduino 24LC256 kütüphanesinde iki tane yazma fonksiyonu var:
Alıntı Yap
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) 
{
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.write(data);
  Wire.endTransmission();
 
  delay(5);
}


We start transmission to our device (I2C) address. Next we send 2 bytes which define the memory location we are writing to. Then finally the one byte of data we are storing.

A small delay is required to give time for the eeprom to save the data.

So far so good. Now, the 24LC256 eeprom has a feature called page write. This allows you to send up to 64 bytes of data before it needs to be saved. We can extend our writeEEPROM routine to perform this function. The routine can be re-written to that shown below.
void writeEEPROM(int deviceaddress, unsigned int eeaddress, char* data) 
{
  // Write a string of chars to eeprom
  // DO NOT USE THIS CODE - IT DOES NOT WORK 
  unsigned char i=0;
  
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)((address) >> 8));   // MSB
  Wire.write((int)((address) & 0xFF)); // LSB

  do{ 
     Wire.write((byte) data[i]);
     i++;
  } while(data[i]);  
  Wire.endTransmission();
     
  delay(6);  // needs 5ms for page write
}

Sayfa(page) boyutu herhalde toplam hafıza boyutuyla orantılı. Çünkü ben page size'ı 24C512 içinn 128 diyebiliyorum. 256 için 64 byte imiş...