www.mikrocontroller.net

Forum: Compiler & IDEs I2C EEPROM


Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

kann mir jemand helfen ?
ich möchte empfangene messewerte in ein serielles EEPROM reinschreiben 
und diese dann später
über die serielle Schnittstelle an ein PC-Programm übermitteln.

Mein primäres Problem ist die empfangene Messwerte in ein serielles 
EEPROM zu schreiben und
zu lesen. Nicht in das interne EEPROM des Prozessors.
Ich weis nur soviel das es mit dem I2C Bus funktioniert muss.
Gehe ich richtig in der Annahme das ich 2 Portpins (freiwählbar)benötige 
für SDA und SCL ?
Wie realisiere ich das in einem C programm ?

Kann mir jemand bei meinem problem helfen.
Im voraus besten Dank

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
siehe FAQ:
Gibt es irgendwo I2C-Funktionen für avr-gcc?
Fertige I2C-Routinen findet man z.B. auf 
http://www.mysunrise.ch/users/pfleury/avr-software.html.

Autor: kitesurfer1404 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin moin!

Ich grabe mal diesen alten Beitrag aus, anstatt einen neuen zu eröffnen.

Nachdem ich an der I2C Ansteuerung der Chipkarte von Reichelt 
gescheitert bin, habe ich mir erstmal EEPROM im DIP8 Gehäuse 
vorgenommen. Leider ebenfalls ohne Erfolg.

Ich habe breits eine selbstgeschriebene Routine, die Atmel Aplication 
Note (avr300.asm) und die im Anhang befindliche Datei i2c.inc getestet. 
Ich glaub, die kam auch aus diesem Forum. Habe die Übersicht inzwischen 
verloren.

Als Controller nutze ich einen Mega8 (interner Oszi 1Mhz), der eeprom 
ist ein M24C64. Im Anhang ist ebenfalls ein Schaltplan, wie das Ding am 
Mega8 dran hängt. Allerdings nutze ich PIN 4 und 5 vom Port B.

An Port D hängen ein paar LEDs.

Das soll passieren:
  LEDs immer abwechselnd schalten (1: ein, 2: aus, 3: ein ...)
  Daten in den EEPROM schreiben (neues "LED-Muster")
  Daten aus EEPROM lesen
  LEDs schalten.

Das passiert:
  LEDs blitzen kurz auf, gehen aus, bleiben aus.

Die Routine "i2cread" gibt für SRAMDAT immer 0x00 zurück. es wird, wie 
es scheint, nichts gelesen. Oder zuvor nichts geschrieben, das kann ich 
leider nicht feststellen.

Alle Verdindungen und Kontakte wurden geprüft.
Wenn ich das Lesen aus dem Speicher und Ausgeben an Port D in die 
Schleife verlege, zeigt das Oszilloskop am SDA Pin am Speicher lustiges 
Gewackel, was bestimmt Daten sind ;-) Der SCL Pin liegt dauerhaft auf 
low.

Vielleicht hat ja jemand ein funktionierendes Programm in asm (oder auch 
schon hex) das ich ausprobieren kann oder entsprechend anpassen kann.

Ich hoffe, ihr könnt mir weiterhelfen. Schonmal vielen Dank im Voraus.


Autor: Frank Jonischkies (frajo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Als Controller nutze ich einen Mega8 (interner Oszi 1Mhz), der eeprom
> ist ein M24C64. Im Anhang ist ebenfalls ein Schaltplan, wie das Ding am
> Mega8 dran hängt. Allerdings nutze ich PIN 4 und 5 vom Port B.

Der Mega8 hat eine Hardware TWI(I2C) die an den Pins PC4(SDA) und 
PC5(SCL) angeschlassen ist. Wenn Du andere Portpins verwendest, mußt Du 
das gesammte I2C Protokoll selbst programmieren (Software I2C). Einfach 
ist es aber den eingebauten (und bezahlten) Hardware I2C des Mega8 zu 
verwenden.

Autor: kitesurfer1404 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Hardware TWI hab ich schon getestet... Leider auch ohne Erfolg. Hast 
du da Code für, den ich verwenden kann? Dann würd ich das nochmal 
testen.

In der i2c.inc sind die entsprechenden Software I2C Routinen drin.

Autor: Frank Jonischkies (frajo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du den Hardware TWI verwendest, kannst Du so vorgehen. Die 
Leitungen SDA und SCL müssen über je einen Widerstand von ca. 4,7KOhm an 
die Versorgungsspannung gelegt werden.
Zuerst mußt Du die Baudrate einstellen:
TWBR = (F_CPU / 100000UL - 16) / 2;  // TWI Baudrate 100KHz
F_CPU sollte im makefile eingetragen sein.
Jede Übertragung beginnt mit einer Startcondition und endet mit einer 
Stopcondition. Dafür machst Du zwei Funktionen. Etwa so:
void TwiStart(void) {
  TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); // send start condition
  while ((TWCR & _BV(TWINT)) == 0) ; // wait for transmission
}

void TwiStop(void {
  TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
}
Außerdem brauchst Du noch eine Funktion zum Senden und eine zum 
Emfangen:
void TwiSend(uint8_t DataByte, uint8_t ackno) {
  TWDR = DataByte;
  if(ackno == 1) TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN);
  else TWCR = _BV(TWINT) | _BV(TWEN); // clear interrupt to start transmission
  while ((TWCR & _BV(TWINT)) == 0) ; // wait for transmission
}

uint8_t TwiReceive(uint8_t ackno) {
  uint8_t DataByte;
  if(ackno == 1) TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN);
  else TWCR = _BV(TWINT) | _BV(TWEN);  // clear interrupt to start transmission
  while ((TWCR & _BV(TWINT)) == 0) ;   // wait for transmission
  DataByte = TWDR;
  return DataByte;
}
Mit dem Parameter ackno steuerst Du ob ein Acknowledge erwartet wird 
oder nicht. Bei nur einem Byte und beim letzten emfangenen oder 
gesendeten Byte ist ackno 0(Null).
Jeder I2C Chip hat eine Basisadresse welche Du im Datenblatt findest. 
Mein 24C256 hat 0xA0 und er braucht eine 16Bit Adresse.
#define TWI_SLA_EE  0xA0
Um nun auf den Speicher zu schreiben oder zu lesen kombinierst Du die 
obigen Funktionen wie erforderlich:
void MemByteWrite(uint16_t addr, uint8_t wert) {
  TwiStart();
  TwiSend(TWI_SLA_EE | TW_WRITE, 0);
  TwiSend(addr >> 8, 0);
  TwiSend(addr, 0);
  TwiSend(wert, 0);
  TwiStop();
}

uint8_t MemByteRead(uint16_t addr) {
  TwiStart();
  TwiSend(TWI_SLA_EE | TW_WRITE, 0);
  TwiSend(addr >> 8, 0);
  TwiSend(addr, 0);
  TwiStart();
  TwiSend(TWI_SLA_EE | TW_READ ,0);
  uint8_t wert = TwiReceive(0);
  TwiStop();
  return wert;
}
Um zugriff auf die Symbole TW_WRITE und TW_READ zu erhalten mußt Du die 
twi.h aus dem compat Verzeichnis includieren:
#include <compat/twi.h>

Nun zu ackno. Wen mehr als ein Byte gelesen oder geschrieben werden 
sollen geht das etwa so:
uint16_t MemWordRead(uint16_t addr) {
  TwiStart();
  TwiSend(TWI_SLA_EE | TW_WRITE, 0);
  TwiSend(addr >> 8, 0);
  TwiSend(addr, 0);
  TwiStart();
  TwiSend(TWI_SLA_EE | TW_READ ,0);
  uint16_t wert = TwiReceive(1);
  wert <<= 8;
  wert += TwiReceive(0);
  TwiStop();
  return wert;
}
Hoffe das hilft etwas. Achtung! Es wird hier keine Fehlerbehandlung 
vorgenommen. Nach jeder Operation kannst Du den Erfolg oder Misserfolg 
durch zuweisen von TW_STATUS auswerten:
 uint8_t twst = TW_STATUS;

Gruß
Frank.

Autor: Frank Jonischkies (frajo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falls Dein Speicher einen WP(write protect) Anschluss hat, muss der an 
Masse. Ebenso die drei(?) Adressleitungen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für die 24Cxx-EEPROMs gibt's in der avr-libc auch Beispielcode für
Hardware-TWI.

Autor: Frank Jonischkies (frajo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, sehe gerade das die twi.h nun im util Verzeichnis liegt. Also 
richtig:
#include <util/twi.h>

  

Autor: kitesurfer1404 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
muss mich erstmal in C für avr einarbeiten und gucken wie ich das auf 
meiner linux maschine zum laufen bekomme...

vielen dank schonmal!

Autor: Frank Jonischkies (frajo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieh mal hier:
Beitrag "avr-gcc toolchain unter puppy linux"
Geht bei mir sogar unter PuppyLinux.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

habe was ähnliches damit gemacht:

http://www.myavr.de/shop/artikel.php?artID=65

... also die I2C leitungen sind am m8 festgelegt C6 und C7 für 
hardware-TWI
frei wählbar wirds nur wenn du mit soft-TWI arbeitest, das twi-protokoll 
ist aber nicht so simpel wie uart oder spi ob die win-avr bibliotheken 
soft-TWI her geben bezweifle ich... Wenn du aber das hardware-TWI nimmst 
solltes du es mit den TWI-bibliotheken hin bekommmen... habs sie selber 
aber noch nicht benutzt, ich habs mit dem code-wizard vom myavr-workpad 
gemacht.


J.

Autor: kitesurfer1404 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
magst du mir die TWI-bibliotheken mal schicken?
mit der software kann ich leider nichts anfangen... bin linux user...

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.