I2C Schnittelle mit EEPROM

Maik15

Neues Mitglied
06. Sep. 2009
55
0
0
Sprachen
Schönen Abend zusammen

Ich brauch schon wieder etwas Rat

Zurzeit will ich mit einer I2C bzw. TWI Schnittelle ein Externes EEPROM beschreiben und auslesen.

In fast alle Quelle ist zu dem Thema zu lesen „geht ganz leicht und ohne Probleme“.
Aber bei mir mal wieder nicht.

Der Original Code aus einem Buch geht nicht und mein angepasstes Programm natürlich auch nicht.

Beim Kompilieren kommen immer 3 Warnungen
c:/../avr/include/util/delay.h:85:3: warning: #warning "F_CPU not defined for <util/delay.h>"

c:/../avr/include/util/delay.h:90:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"

../i2c_test.c:133: warning: large integer implicitly truncated to unsigned type


Alle beziehen sich auf die Programmzeile
Code:
 TWBR = (F_CPU / 100000UL - 16) / 2;	// TWI Baudrate 100KHz

Weiß eine damit was anzufangen?

Und meine zweite Frage wäre: Wie kann ich die Hardware Testen.

Ich hab zwischendurch die LED's am Bord blinken lassen wenn ein Programmabschnitt abgearbeitet ist und über das TWSR Register die ACK Rückmeldung ausgewertet und da ging er ein paar mal auf Störung weil das Signal nicht kam.

Aber ansonsten lief das Programm durch aber es würde nie ein ausgelesener Wert an den LED's angezeigt.

Das ist das Original Programm.
Bei meinem sind die Funktionen unter dem main und die Adressierung ist anders aber beide Programme haben das gleiche Problem.

Code:
/* I²C (TWI) Bus
 *
 * Speichert Werte in einem externen EEPROM
 *
 * Liest die Werte wieder aus und zeigt sie auf den LEDs an
 *
 */

#include <avr/io.h>
#include <util/delay.h>

#define BASEADR		0xA0	// Basisadresse des EEPROMs 24C16, Page 0
#define TW_READ		1		// LSB bei Busadresse zur Kennzeichnung eines Lesezugriffes
#define TW_WRITE	0		// LSB bei Busadresse zur Kennzeichnung eines Schreibzugriffes

void delay_ms(uint16_t);
void i2c_start(void);
void i2c_stop(void);
void i2c_send(uint8_t) ;
uint8_t i2c_receive(uint8_t);
void EEPROM_ByteWrite(uint16_t, uint8_t);
uint8_t EEPROM_ByteRead(uint16_t);
int main(void);

// wartet ms Millisekunden
void delay_ms(uint16_t ms)
{
	for(uint16_t t=0; t<=ms; t++)
		_delay_ms(250); 
}

/**
	@brief	Startanweisung senden
	@param	none
	@return	none
*/
void i2c_start(void) 
{
	TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); 	// send start condition
	while ((TWCR & _BV(TWINT)) == 0) ; 				// wait for transmission
}

/**
	@brief	Stopanweisung senden
	@param	none
	@return	none
*/
void i2c_stop(void) 
{
	TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);		// send stop condition
}

/**
	@brief	Datenbyte senden
	@param	Byte
	@return	none
*/
void i2c_send(uint8_t DataByte) 
{
	TWDR = DataByte;
	TWCR = _BV(TWINT) | _BV(TWEN); 			// clear interrupt to start transmission
	while ((TWCR & _BV(TWINT)) == 0) ; 		// wait for transmission
}

/**
	@brief	Datenbyte empfangen
	@param	ACK senden (1) oder nicht (0)
	@return	none
*/
uint8_t i2c_receive(uint8_t ack) 
{
	if (ack == 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
	return TWDR; 
}

/**
	@brief	Byte im EEPROM an Adresse speichern
	@param	Adresse, Datenbyte
	@return	none
*/
void EEPROM_ByteWrite(uint16_t addr, uint8_t wert) 
{
again:
	i2c_start();
	i2c_send(BASEADR | TW_WRITE);

	// Pruefen, ob Adressbyte angenommen wurde
	if ((TWSR & 0xF8) != 0x18)
	{
		i2c_stop();
		goto again;
	}

	//  i2c_send(addr >> 8, 0);		// bei 16-Bit Adressierung HSB zuerst
	i2c_send(addr);

	i2c_send(wert);
	i2c_stop();
	_delay_ms(5);			// warten fuer 24Cxx
}

/**
	@brief	Byte aus EEPROM von Adresse lesen
	@param	Adresse
	@return	Datenbyte
*/
uint8_t EEPROM_ByteRead(uint16_t addr) 
{
	uint8_t wert;
	
	i2c_start();
	i2c_send(BASEADR | TW_WRITE);

	//  i2c_send(addr >> 8, 0);		// bei 16-Bit Adressierung HSB zuerst
	i2c_send(addr);

	i2c_start();
	i2c_send(BASEADR | TW_READ);
	wert = i2c_receive(0);
	i2c_stop();
	return wert;
}

int main(void)
{
	uint8_t wert=0;
	
	DDRB = 0xFF;							// Port B (LEDs) als Ausgang
	TWBR = (F_CPU / 100000UL - 16) / 2;		// TWI Baudrate 100KHz

	EEPROM_ByteWrite(0,0b11110000);		// Wert im EEPROM an Adresse 0 (Page 0) speichern
	EEPROM_ByteWrite(1,0b00001111);		// Wert im EEPROM an Adresse 1 (Page 0) speichern
	EEPROM_ByteWrite(2,0b10101010);		// Wert im EEPROM an Adresse 1 (Page 0) speichern

	wert = EEPROM_ByteRead(0);			// Wert aus EEPROM Adresse 0 (Page 0) auslesen
	PORTB = wert;						// Wert auf LEDs anzeigen
	delay_ms (2000);					// 2 s warten

	wert = EEPROM_ByteRead(1);			// Wert aus EEPROM Adresse 1 (Page 0) auslesen
	PORTB = wert;						// Wert auf LEDs anzeigen
	delay_ms (2000);					// 2 s warten

	wert = EEPROM_ByteRead(2);			// Wert aus EEPROM Adresse 2 (Page 0) auslesen
	PORTB = wert;						// Wert auf LEDs anzeigen

	return 0;
}

gruß
Maik
 
Was hast Du für eine IDE?

Zum Debuggen verwende ich meistens einen USART und gebe dort die Rückgabewerte der Funktionen und etc. aus.

Grüsse
Heinrich
 
Hallo Maik,

ich habe mir jetzt die I2C-Routinen nicht genau angesehen, die Warnung bei dir kommt, weil F_CPU nicht explizit definiert ist, das solltest du vor #include <util/delay.h> machen:

#define F_CPU 16000000UL // hier als beispiel 16MHz

Ich glaube bei deiner Delayroutine mußt du _delay_ms(1); verwenden, nicht _delay_ms(250).

Du nutzt sicherlich WinAVR. Stelle die Compiler-Optimierung auf -Os.

Grüße,
Dirk
 
Beim Eclipse wird F_CPU in den Projekteigenschaften eingestellt. Beim AVR Studio eigentlich genau so, wenn man denn macht.

Ich habe ein komplettes Program für RTC lesen und schreiben, wenn Du willst, lade ich es kurz hoch.

Grüsse
Heinrich
 
Hallo Heinrich,

Ich habe ein komplettes Program für RTC lesen und schreiben, wenn Du willst, lade ich es kurz hoch.
würde mich auch interessieren, da ich ja bei meinem Assembler auch noch ein
paar Probleme mit I2C/TWI habe ;) evtl kann ich ja noch was lernen:D

Gruß
Dino
 
So, hier, bitte schön.

Es ist ein vollständiges Eclipse-Projekt, also einfach im Workspace auspacken und loslegen. Das Ding ist für AtMega32 gebaut.

Grüsse
Heinrich
 

Anhänge

  • RTC32.zip
    31 KB · Aufrufe: 27
Wieso hab ich auf jede Antwort nur noch mehr Fragen? :confused:

1. Was ist ein IDE?
Aber meine Standart Antwort ist ATmega644; AVR-Studio 4.17; WIN-AVR
als C Compiler und das Bord STK500.

2. delay_ms(1)
hatte ich eigentlich Standart mäßig aber beim dem vielem Rumprobieren
und dann hier Posten hatte ich es vergessen wieder zurück zu stellen.

3. Die Compiler-Optimierung steht auf -00 bei -0s wird es so stark Optimiert
das Teile des Codes beim Simulieren nicht mehr abgearbeitet wird.

4. Projekteigenschaften einstellen was wo wie?
Muss man so was machen?

5. RTC ???
Also mit RTW könnte ich noch was anfangen.
Und laut Google bzw Wiki steht entweder für
Rad Touristik Club;
Real-Time Center AG mit Sitz in Köniz;
....
Aber ich denke mal es geht um eine Echt Zeit Uhr.

Wäre nett wenn Du das Programm hoch laden kannst.
Ich würde mich freuen mal einen anderen Code (wenn er in C ist) zu sehen.
Da sieht man es vielleicht am besten was oder wie es anders geht.

gruß
Maik
 
Hallo,

1. Was ist ein IDE?
Aber meine Standart Antwort ist ATmega644; AVR-Studio 4.17; WIN-AVR
als C Compiler und das Bord STK500.
IDE müßte nach meinere Meinung "Integrated Design Environment" heißen.
Also eine "Integrierte Entwicklungs-Umgebung". Das sind dann Editor,
Compiler, Debugger, ... in einer Oberfläche zusammengefaßt. So wie bei
Officepaketen die Tabellenkalkulation, Textverarbeitung, Datenbank,
Grafik unter einer Oberfläche laufen.

2. delay_ms(1)
hatte ich eigentlich Standart mäßig aber beim dem vielem Rumprobieren
und dann hier Posten hatte ich es vergessen wieder zurück zu stellen.

3. Die Compiler-Optimierung steht auf -00 bei -0s wird es so stark Optimiert
das Teile des Codes beim Simulieren nicht mehr abgearbeitet wird.

4. Projekteigenschaften einstellen was wo wie?
Muss man so was machen?
Da muß ich wohl auch noch mal rumsuchen was man wo einstellen muß.

5. RTC ???
Also mit RTW könnte ich noch was anfangen.
Und laut Google bzw Wiki steht entweder für
Rad Touristik Club;
Real-Time Center AG mit Sitz in Köniz;
....
Aber ich denke mal es geht um eine Echt Zeit Uhr.
Jau ! "Real Time Clock" ;)

Wäre nett wenn Du das Programm hoch laden kannst.
Ich würde mich freuen mal einen anderen Code (wenn er in C ist) zu sehen.
Da sieht man es vielleicht am besten was oder wie es anders geht.
Genau so mach ich es auch immer. Bei anderen nachsehen wie die es
gelöst haben und rumprobieren wo man was verbessern, übernehmen oder
anpassen kann. Warum soll man das Rad immer wieder neu erfinden ? ;)

Gruß
Dino
 
Servus Ihr Beiden,

das Programm habe ich hochgeladen, hängt am Beitrag über dem von Maik.

Grüsse
Heinrich
 
Hi Hemi danke dir nochmal.
Hat mir zwar diesmal nicht so recht geholfen da ich das Programm noch nicht hab.
Und im Texteditor ist das Programm nicht so recht lesbar da alles aneinander gereit steht.

Aber das Programm von mir funktioniert jetzt.

Heute morgen kam mir die Idee. :stupido2:
Les dir doch noch mal das Datenblatt vom EEPROM durch.
Und keine 10min später bin ich über den WP Eingang gestolpert (da war doch was???).
Dan viel es mir wieder ein Schreibschutz der PIN gehört an Masse.

Dann ging es auch Problemlos, sogar mein Programm man bin ich stolz auf mich.:adore:

P.S. komisch ich wünsch mich seit Wochen in meine Lehrzeit zurück.
Da haben wir nur mit Widerständen, Transistoren und ein paar Elkos rumgespielt und die Welt war noch in Ordnung.
Aber der ganze Softwaremist macht einen Betriebsblind für Hardwarefehler.

gruß
Maik
 
Bei mir wird der Code von Hemi auch richtig angezeigt, es kann schon am Editor liegen, Maik lade den Code mal mit eimem anderen Editor oder gleich mir AVR-Studio.

@Hemi: Ich habe zwar selber schon einige male I2C verwendet, aber ich darf mir doch deinen Code sicherlich mal speichern, der ist nämlich schön sauber geschrieben :) ;)

@Maik: Dann mal herzlichen Glückwunsch :D Siehst du, jetzt klappts sogar mit dem EEPROM ;)

Schönen Abend noch,
Dirk
 
Hallo Maik,

Bei mir wird der Code von Hemi auch richtig angezeigt, es kann schon am Editor liegen, Maik lade den Code mal mit eimem anderen Editor oder gleich mir AVR-Studio.
seh ich auch so :D :rolleyes:
Der Notepad von Windows ist totaler Schrott ! Da habe ich auf der Arbeit auch
immer schöne Probleme mit wenn man Cisco-Configs anzeigen will. Alles in einer
Zeile.

Das kommt daher weil DOS/Windows mit CRLF (Carriage Return / Line Feed) als
Zeilenende arbeitet und Linux,... nur mit LF (Line Feed).

Ich benutze als Standard-Editor jetzt den Notepad++
Früher hab ich den TextPad4 verwendet. Aber der ist nicht vollständig frei.
Darum bin ich auf den Notepad++ umgestiegen. Wesentlich besser als die
Windows-Krücke :cool:

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)