Bot-Builder
11.03.2013, 13:33
Hallo alle Zusammen,
ich mache gerade meine ersten Schritte mit I2C. Und habe gleich schon meine ersten Probleme.
Ich habe einen 24C512 an einen ATMega8 über Hardware TWI, also PIN 27 und 28 angeschlossen, 4k7 Pullups vorhanden, die Adressen des 24C512 wie im Code gezeigt setzt, Spannung und Masse verbunden. Also alles in Minimalkonfiguration.
Als Lib verwende ich die von Peter Fleury ohne irgendwelche Änderungen.
Ich möchten den Wert der Speicherstelle 0x05 auslesen, um Eins erhöhen und an die gleiche Speicherstelle zurück schreiben. Die Werte sollen auf einem LCD dargestellt.
Mein Programm sieht wie folgt aus:
/*-------+---------+---------+---------+---------+---------+---------+---------+
* #include-Dateien
*--------+---------+---------+---------+---------+---------+---------+---------+*/
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include "lcd.h"
#include "i2cmaster.h"
/*-------+---------+---------+---------+---------+---------+---------+---------+
Prototypen():
---------+---------+---------+---------+---------+---------+---------+---------+*/
void Fehler(uint8_t Schritt);
/*-------+---------+---------+---------+---------+---------+---------+---------+
Funktionen():
---------+---------+---------+---------+---------+---------+---------+---------+*/
//-------+---------+---------+---------+---------+---------+---------+---------+
// void Fehler(uint8_t Schritt):
/** @brief gibt eine Fehlermeldung aus */
/** @param (Programm-)Schritt in der der Fehler aufgetreten ist */
/** @return keinen Rückgabewert */
//-------+---------+---------+---------+---------+---------+---------+---------+
void Fehler(uint8_t Schritt)
{
switch(Schritt)
{
case 1:
lcd_gotoxy(0,2); lcd_puts("ERR: 1. Start");
break;
case 2:
lcd_gotoxy(0,2); lcd_puts("ERR: 1. Adresse");
break;
case 3:
lcd_gotoxy(0,2); lcd_puts("ERR: READ-Modus");
break;
case 4:
lcd_gotoxy(0,2); lcd_puts("ERR: 2. Start");
break;
case 5:
lcd_gotoxy(0,2); lcd_puts("ERR: 2. Adresse");
break;
case 6:
lcd_gotoxy(0,2); lcd_puts("ERR: Schreiben");
break;
default:
lcd_gotoxy(0,2); lcd_puts("unbekannter Fehler.");
}
i2c_stop();
while(1);
}
//-------+---------+---------+---------+---------+---------+---------+---------+
// main(void)
/** @brief LCD initialisieren. \n
I2C Kommunikation initialisieren. \n
Wert aus Speicherstelle 0x05 auslesen, \n
um Eins erhöhen, \n
und an die gleich Stelle zurückschreiben.
Beide Werte dann auf dem LCD darstellen. \n*/
/** @param keine Übergabeparameter */
/** @return 0 */
//-------+---------+---------+---------+---------+---------+---------+---------+
int main(void)
{
/** @brief Returnwert aus den Funktionen zur Fehlerkontrolle */
uint8_t ret;
/** @brief aus dem Speicher ausgelesen bzw. zurück geschriebene
Werte. */
uint8_t WertAlt;
uint8_t WertNeu;
/** @brief Zwischenspeicher für Ausgabe */
char Ausgabe[13];
// LCD initialisieren
lcd_init(LCD_DISP_ON); lcd_command(LCD_BACKLIGHT_ON);
// initialize I2C library
i2c_init();
// read value from 24C512 EEPROM address 5
// 24C512 adress set to A2 = 0, A1 = 1, A0 =1
i2c_start_wait(0b10100110+I2C_WRITE); // set device address and write mode
/* oder auch
ret= i2c_start(0b10100110+I2C_WRITE); // set device address and write mode
if ( ret ) Fehler(2);
*/
ret = i2c_write(0x05); // write address = 5
if ( ret ) Fehler(2);
ret = i2c_rep_start(0b10100110+I2C_READ); // set device address and read mode
if ( ret ) Fehler(3);
WertAlt = i2c_readNak(); // read one byte from EEPROM
i2c_stop();
WertNeu = WertAlt + 1;
// write value to 24C512 EEPROM address 5 (Byte Write)
i2c_start_wait(0b10100110+I2C_WRITE); // set device address and write mode
/* oder auch
ret= i2c_start(0b10100110+I2C_WRITE); // set device address and write mode
if ( ret ) Fehler(4);
*/
ret = i2c_write(0x05); // write address = 5
if ( ret ) Fehler(5);
ret = i2c_write(WertNeu); // write value 0x75 to EEPROM
if ( ret ) Fehler(6);
i2c_stop(); // set stop conditon = release bus
lcd_gotoxy(0,1); utoa(WertAlt, Ausgabe, 10); lcd_puts("Alt: "); lcd_puts(Ausgabe);
lcd_gotoxy(0,2); utoa(WertNeu, Ausgabe, 10); lcd_puts("Neu: "); lcd_puts(Ausgabe);
while(1);
return 0;
}
Als Werte erhalte ich aber immer nur als gelesen Wert 255 und als geschriebene Wert 0. Was für den ersten Durchlauf des Programmes noch in Ordnung wäre. Wenn ich dann aber einen Reset am Controller auslöse und das Programm von vorn beginnt, sollte als gelesen 0 und geschrieben 1 erscheint. Tut es aber wie gesagt leider nicht, immer nur 255 und 0.
Ich sehe das doch richtig, dass alle Speicherstellen in einem fabrikneuen 24C512 mit 255 beschrieben sind. Somit müsste zumindest das Auslesen funktionieren, oder?
Die I2C-Funktionen erzeugen keinen Fehlercode. Kann ich dann davon ausgehen, dass der Code korrekt abgearbeitet wird? Und vor allem kann ich damit einen Hardwarefehler ausschließen?
Oder habe ich gerade ein Brett vor dem Kopf und sehe den Wald vor lauter Bäumen nicht mehr?
Bin für jeden Hinweis dankbar.
Vielen Dank
Bot-Builder
ich mache gerade meine ersten Schritte mit I2C. Und habe gleich schon meine ersten Probleme.
Ich habe einen 24C512 an einen ATMega8 über Hardware TWI, also PIN 27 und 28 angeschlossen, 4k7 Pullups vorhanden, die Adressen des 24C512 wie im Code gezeigt setzt, Spannung und Masse verbunden. Also alles in Minimalkonfiguration.
Als Lib verwende ich die von Peter Fleury ohne irgendwelche Änderungen.
Ich möchten den Wert der Speicherstelle 0x05 auslesen, um Eins erhöhen und an die gleiche Speicherstelle zurück schreiben. Die Werte sollen auf einem LCD dargestellt.
Mein Programm sieht wie folgt aus:
/*-------+---------+---------+---------+---------+---------+---------+---------+
* #include-Dateien
*--------+---------+---------+---------+---------+---------+---------+---------+*/
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include "lcd.h"
#include "i2cmaster.h"
/*-------+---------+---------+---------+---------+---------+---------+---------+
Prototypen():
---------+---------+---------+---------+---------+---------+---------+---------+*/
void Fehler(uint8_t Schritt);
/*-------+---------+---------+---------+---------+---------+---------+---------+
Funktionen():
---------+---------+---------+---------+---------+---------+---------+---------+*/
//-------+---------+---------+---------+---------+---------+---------+---------+
// void Fehler(uint8_t Schritt):
/** @brief gibt eine Fehlermeldung aus */
/** @param (Programm-)Schritt in der der Fehler aufgetreten ist */
/** @return keinen Rückgabewert */
//-------+---------+---------+---------+---------+---------+---------+---------+
void Fehler(uint8_t Schritt)
{
switch(Schritt)
{
case 1:
lcd_gotoxy(0,2); lcd_puts("ERR: 1. Start");
break;
case 2:
lcd_gotoxy(0,2); lcd_puts("ERR: 1. Adresse");
break;
case 3:
lcd_gotoxy(0,2); lcd_puts("ERR: READ-Modus");
break;
case 4:
lcd_gotoxy(0,2); lcd_puts("ERR: 2. Start");
break;
case 5:
lcd_gotoxy(0,2); lcd_puts("ERR: 2. Adresse");
break;
case 6:
lcd_gotoxy(0,2); lcd_puts("ERR: Schreiben");
break;
default:
lcd_gotoxy(0,2); lcd_puts("unbekannter Fehler.");
}
i2c_stop();
while(1);
}
//-------+---------+---------+---------+---------+---------+---------+---------+
// main(void)
/** @brief LCD initialisieren. \n
I2C Kommunikation initialisieren. \n
Wert aus Speicherstelle 0x05 auslesen, \n
um Eins erhöhen, \n
und an die gleich Stelle zurückschreiben.
Beide Werte dann auf dem LCD darstellen. \n*/
/** @param keine Übergabeparameter */
/** @return 0 */
//-------+---------+---------+---------+---------+---------+---------+---------+
int main(void)
{
/** @brief Returnwert aus den Funktionen zur Fehlerkontrolle */
uint8_t ret;
/** @brief aus dem Speicher ausgelesen bzw. zurück geschriebene
Werte. */
uint8_t WertAlt;
uint8_t WertNeu;
/** @brief Zwischenspeicher für Ausgabe */
char Ausgabe[13];
// LCD initialisieren
lcd_init(LCD_DISP_ON); lcd_command(LCD_BACKLIGHT_ON);
// initialize I2C library
i2c_init();
// read value from 24C512 EEPROM address 5
// 24C512 adress set to A2 = 0, A1 = 1, A0 =1
i2c_start_wait(0b10100110+I2C_WRITE); // set device address and write mode
/* oder auch
ret= i2c_start(0b10100110+I2C_WRITE); // set device address and write mode
if ( ret ) Fehler(2);
*/
ret = i2c_write(0x05); // write address = 5
if ( ret ) Fehler(2);
ret = i2c_rep_start(0b10100110+I2C_READ); // set device address and read mode
if ( ret ) Fehler(3);
WertAlt = i2c_readNak(); // read one byte from EEPROM
i2c_stop();
WertNeu = WertAlt + 1;
// write value to 24C512 EEPROM address 5 (Byte Write)
i2c_start_wait(0b10100110+I2C_WRITE); // set device address and write mode
/* oder auch
ret= i2c_start(0b10100110+I2C_WRITE); // set device address and write mode
if ( ret ) Fehler(4);
*/
ret = i2c_write(0x05); // write address = 5
if ( ret ) Fehler(5);
ret = i2c_write(WertNeu); // write value 0x75 to EEPROM
if ( ret ) Fehler(6);
i2c_stop(); // set stop conditon = release bus
lcd_gotoxy(0,1); utoa(WertAlt, Ausgabe, 10); lcd_puts("Alt: "); lcd_puts(Ausgabe);
lcd_gotoxy(0,2); utoa(WertNeu, Ausgabe, 10); lcd_puts("Neu: "); lcd_puts(Ausgabe);
while(1);
return 0;
}
Als Werte erhalte ich aber immer nur als gelesen Wert 255 und als geschriebene Wert 0. Was für den ersten Durchlauf des Programmes noch in Ordnung wäre. Wenn ich dann aber einen Reset am Controller auslöse und das Programm von vorn beginnt, sollte als gelesen 0 und geschrieben 1 erscheint. Tut es aber wie gesagt leider nicht, immer nur 255 und 0.
Ich sehe das doch richtig, dass alle Speicherstellen in einem fabrikneuen 24C512 mit 255 beschrieben sind. Somit müsste zumindest das Auslesen funktionieren, oder?
Die I2C-Funktionen erzeugen keinen Fehlercode. Kann ich dann davon ausgehen, dass der Code korrekt abgearbeitet wird? Und vor allem kann ich damit einen Hardwarefehler ausschließen?
Oder habe ich gerade ein Brett vor dem Kopf und sehe den Wald vor lauter Bäumen nicht mehr?
Bin für jeden Hinweis dankbar.
Vielen Dank
Bot-Builder