www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik EEPROM 24c16


Autor: Florian idb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

hab mal eine kleine Frage an die C Profis unter euch.

Und zwar würde ich gerne ein EEPROM IC vom Typ 24c16 in C mit meinem 
Atmega8 ansprechen. Allerdings blicke ich bei den ganzen TWI Sachen 
nicht so richtig durch (von der Software her).

Meine Frage ist nun ob jemand von euch das schonmal gemacht hat und mir 
eventuell die Funktionen zum lesen und schreiben eines Bytes zur 
verfügung stellen könnte.Sitze nun schon 3 Wochen dran und bin echt am 
verzweifeln.

Danke im vorraus
Flo

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann dir meinen Q&D Entwurf geben. Ist aber noch nicht getetstet, 
weil ich noch keine Hardware dazu habe. Aber als Ideenspender sollte es 
reichen.

Header i2c.h

#define SDA_LOW DDRB |= (1<<PB0);    // low, open drain
#define SDA_HIGH DDRB &= ~(1<<PB0);    // high, Z

#define SCL_LOW DDRB |= (1<<PB1);    // low, open drain
#define SCL_HIGH DDRB &= ~(1<<PB1);    // high, Z

#define SDA (PINB & (1<<PB0))      // get SDA

void i2c_write_byte(uint16_t address, uint8_t data);
uint8_t i2c_read_byte(uint16_t address);
void i2c_read_block(uint16_t address, uint8_t *buffer, uint16_t count);
void i2c_write_cblock(uint16_t address, uint8_t cnt, uint8_t data);


Source i2c.c

/*

Quick and Dirty I2C Access

*/

#include <avr/io.h>
#include "i2c.h"

void i2c_start(void)
{
  SDA_LOW
  asm("nop");
  SCL_LOW
}

void i2c_stop(void)
{
  SDA_HIGH
  asm("nop");
  SCL_HIGH
}

uint8_t i2c_write(uint8_t data)
{
  uint8_t cnt=8;
  for (; cnt>0; cnt--) {
    if (data & 0x80)
      SDA_HIGH
    else
      SDA_LOW
    SCL_HIGH
    data <<= 1;
    SCL_LOW
  }
  SDA_HIGH
  SCL_HIGH
  asm("nop");              // WICHTG, wegen des Eingangsverzögerung!
  if (SDA) cnt=0; else cnt=1;      // check ACK
  SCL_LOW
  return cnt;
}

uint8_t i2c_read(uint8_t ack)
{
  uint8_t tmp=0, cnt=8;

  for (; cnt>0; cnt--) {
    SCL_HIGH
    tmp <<= 1;
    if (SDA) tmp |= 0x01;
    SCL_LOW
  }
  if (ack) SDA_LOW else SDA_HIGH
  SCL_HIGH
  SCL_LOW
  SDA_HIGH
  return tmp;
}

// ein Byte in den EEPROM per I2C schreiben

void i2c_write_byte(uint16_t address, uint8_t data) {

  i2c_start();
  i2c_write(0xA0);
  i2c_write(address>>8);
  i2c_write(address & 0xFF);
  i2c_write(data);
  i2c_stop();
}

// ein Byte aus dem EEPROM per I2C lesen

uint8_t i2c_read_byte(uint16_t address) {

  uint8_t tmp;

  // Adresse schreiben

  i2c_start();
  i2c_write(0xA0);
  i2c_write(address>>8);
  i2c_write(address & 0xFF);
  i2c_stop();

  // Byte lesen
  i2c_start();
  i2c_write(0xA1);
  tmp=i2c_read(0);
  i2c_stop();

  return tmp;
}

// einen Block aus dem EEPROM per I2C lesen

void i2c_read_block(uint16_t address, uint8_t *buffer, uint16_t count) {

  // Adresse schreiben

  i2c_start();
  i2c_write(0xA0);
  i2c_write(address>>8);
  i2c_write(address & 0xFF);
  i2c_stop();

  i2c_start();
  i2c_write(0xA1);

  while(count>1) {
    *buffer=i2c_read(1);
    buffer++;
  }
  *buffer=i2c_read(0);    // NACK für letztes Byte
  i2c_stop();
}

// einen Block konstanter Daten in den EEPROM scheiben
// Page Ausrichtung muss vom aufrufenden Programm geprüft werden

void i2c_write_cblock(uint16_t address, uint8_t cnt, uint8_t data) {

  // Adresse schreiben

  i2c_start();
  i2c_write(0xA0);
  i2c_write(address>>8);
  i2c_write(address & 0xFF);

  for(; cnt>0; cnt--) {
    i2c_write(data);
  }
  i2c_stop();        // Start des Schreibzugriffs
}

MFG
Falk

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.