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
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.
gruß
Maik
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