www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Erste Schritte mit I2C


Autor: M. T. (cube7)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Pros,

ich bin gerade dabei meine ersten Schritte mit AVR µC und TWI zu machen 
und habe ein Paar allgemeine Fragen.

Was vorhanden ist:

3xATmega 328P
1xSTK500
1xLichtsensor ISL29010 über I2C anbindbar

Ziel: Mein Wunsch ist es nun diesen Lichtsensor über den µC auszulesen, 
so dass bei bestimmten Lichtverhältnissen z.B. eine LED zu Leuchten 
beginnt.

(Die f***ing manuals habe ich natürlich gelesen, okay die vom Atmel nur 
selektiv XD.)

Hier mal n reines Verbindungsschema mit der Frage ob ich irgendetwas 
nicht bedacht habe.

Sensor----STK500(ATmega 328P)

Vdd-------VTG(Zielspannung)
GND----GND
REXT--100kOhm--GND (laut manual)
A0----GND (für Slave-Adresse:1000101x)
SCL----SCL
SDA----SDA
Am STK500 habe ich den Expansion Connector 0 genutzt.

Die erste Frage stellt sich mir beim Programmieren des AVR unter der 
Benutzung von Peter Fleurys I2C library.

 #include <i2cmaster.h>


 #define ISL29010  0x8A      // Sensor x8A = Adresse 10001010
 int main(void)
 {
     unsigned char ret;

     i2c_init();                             // initialize I2C library

     //  
     i2c_start_wait(ISL29010+I2C_READ);     // set device address and write mode
     i2c_read (ret);                        // auslesen ohne ACK 
     i2c_write(ret);                        // write value to EEPROM
     i2c_stop();                             // set stop conditon = release bus

     i2c_stop();

     for(;;);
 }


Würde so bereits das aktuelle Messbyte im EEPROM gespeichert werden, 
obwohl ich nicht einmal das Register angegeben habe in der das Messbyte 
im Sensor liegt, oder gar den Ort an dem es im AVR gespeichert werden 
soll?

Für ein bisschen Unterstützung wäre ich als noop sehr dankbar XD.

Grüße,
M.

P.S.
Gibt es eigentlich eine Alternative für den 100kOhm pull-up Widerstand, 
ich hab momentan keinen zur Hand.

Autor: M. T. (cube7)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat vielleicht sonst bereits jemand Erfahrungen mit dem STK500 und TWI 
gemacht und könnte mir da ein paar Ratschläge geben?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Gibt es eigentlich eine Alternative für den 100kOhm pull-up Widerstand,
> ich hab momentan keinen zur Hand.

Hundert 1k in Serie? 10 1M parallel?
SCNR

Autor: XXX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Soweit ich üerb TWI Bescheid weiß, kann man nicht so einfach zwischen
Schreiben und Lesen umschalten so wie du das machst.
Dazwischen gehört ein STOP-Befehl mit anschließender neuer
Adressierung.

Siehe
//http://pdf1.alldatasheet.com/datasheetpdf/view/224...

Seite 3 und 4.

>>     i2c_start_wait(ISL29010+I2C_READ);     // set device address and write mode


Da stimmt auch was nicht. Laut Funktion willst du lesen, laut
Kommentar willst du schreiben.

Gruß
Joachim

Autor: M. T. (cube7)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah eine hilfreiche Antwort!
Sorry, der Kommentar ist falsch, muss natürlich lesen heißen.
Mit dem Stop befehl bin ich mir nicht sicher, ist zwar nach I2C 
Datasheet notwendig, aber ich verwende ja Peter Fleurys library.

Ich wüsste nur mal gerne ob ich das Prinzip seiner Library richtig 
verstanden habe.

Für weitere hilfreiche Antworten wäre ich dankbar.

Grüße,
M.

Autor: Winfried J. (Firma: Nisch-Aufzüge) (winne)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ne ne des ist quatsch

Um zum Beispiel ab einer gewissen Adresse zu lesen muss als Erste der 
Lesebefehl gesendet werden, dann die Adresse ab der gelesen werden soll, 
unmittelba darauf folgen die Takte zum lesen der Bytes. Beim Lesen des 
letzten Bytes ist die Lücke für das Aknow_Bit zu durch setzen des 
Nack_Bit durch den Sender zu schließen. Darauf erst kann ein Stoppbefehl 
folgen oder mit dem Senden eines neuen Befehls die übertragung 
fortgesetzt werden.

Autor: M. T. (cube7)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Winne,
danke für deine Antwort.
Hmm, dacht ich mit  schon, dass das nicht so einfach ist.

Also nehmen wir mal mein Beispiel und wollen einen Sensor über I2C 
auslesen.
D.h. ich muss zuerst ganz normal I2C initialisieren
#include <i2cmaster.h>


 #define ISL29010  0x8A      // Sensor x8A = Adresse 10001010
 int main(void)
 {
    ....

  i2c_init();                           // I2C lib. initialisieren

      
  i2c_start_wait(ISL29010+I2C_READ);  //Sensor ansprechen und auf ACK warten                  
 }

dann muss ich aus dem entsprechenden Register des Sensors die Messdaten 
auslesen
i2c_read (0x04);   //hier die Addresse des Registers aus der gelesen werden        soll

i2c_read (ret);   // und hier die Variable in der die Daten gespeichert werden sollen????

dann schreibst du
"unmittelba darauf folgen die Takte zum lesen der Bytes"
was ich nicht ganz verstehe, meins du wie lange / wie viele Takte der 
Sensor ausgelesen werden soll und wenn ja, wie reguliert man das, mit 
schleifen?

Grüße,
M.

Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. T. schrieb:
> Hat vielleicht sonst bereits jemand Erfahrungen mit dem STK500 und TWI
> gemacht und könnte mir da ein paar Ratschläge geben?

Was hat denn das STK500 mit TWI zu tun ?

M. T. schrieb:
> (Die f***ing manuals habe ich natürlich gelesen, okay die vom Atmel nur
> selektiv XD.)

Ziemlich schlechte Einstellung ...

Woran erkennst du denn, dass dein Programm nicht funktioniert?

Wie steht's mit Fuses ?

Hier für die Verdrahtung:
http://www.sprut.de/electronic/pic/grund/i2c.htm

Und noch ein Schaltplanbeispiel:
http://www.sprut.de/electronic/pic/grund/i2c_soft.htm

Ist allerdings beides für PIC und nicht für AVR

M. T. schrieb:
> Die f***ing manuals habe ich natürlich gelesen

Wenn du das getan hast dann sollte ja alles klar sein oder? Da steht 
doch alles drin. Man muss nur genau lesen und sich Zeit nehmen. Wir 
können auch nur das Datenblatt lesen.

Außerdem solltest du die Libraries nur verwenden wenn du sie auch 
verstehst.

Ansonsten überleg dir ob nicht eine diskrete Schaltung für dich besser 
geeignet ist...

Autor: M. T. (cube7)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Michael,
eigentlich geht es mir in meinem Thread nicht darum diesen 
Programmschnipsel zum laufen zu bringen, sondern besser I2C zu 
verstehen.
Nur vom lesen irgendwelcher manuals wird man aber weder programmieren 
lernen, noch TWI verstehen.
Um die Fuses mach ich mir momentan noch keine Gedanken, da ich das 
Programm ja nicht einmal gebrannt habe - wie gesagt ich will erst einmal 
die Grundlagen verstehen.

Grüße,
M

P.S.
Danke für die Links, ich glaube die helfen mir wieder ein Stück 
weiter:-)!

Autor: Winfried J. (Firma: Nisch-Aufzüge) (winne)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch vergessen jede übertragung muss mit einer startconition beginnen 
und mit einer stoppcondition enden

hier wird eine Uhr DS3231 gelesen und gestellt ()nur die zeit)

lesen aus der TWI

TWI_STARTCONDITION();
TWI_SLA_W (clock_SLA_W);
TWI_SENDDATA (0x00);
TWI_RSTARTCONDITION();
TWI_SLA_R (clock_SLA_R);
s0=TWI_RECIVEDATA_ACK ();
m0=TWI_RECIVEDATA_ACK ();
h0=TWI_RECIVEDATA_NACK ();
TWI_STOPCONDITION();


schreiben in die TWI


TWI_STARTCONDITION();
TWI_SLA_W (clock_SLA_W);
TWI_SENDDATA (0x00);
TWI_SENDDATA (s0);
TWI_SENDDATA (m0);
TWI_SENDDATA (h0);
TWI_STOPCONDITION();


die Funtkionen dazu

.....


hier noch was zu I²C

char
TWINT=7
TWEA=6
TWSTA=5
TWSTO=4
TWWC=3
TWEN=2
TWIE=0

START=0x08
RSTART=0x10
MT_SLA_ACK=0x18
MT_DATA_ACK=0x28
MR_SLA_ACK=0x40
MR_DATA_ACK=0x50
SLA_W1=0xa0
SLA_W2=0xa2
SLA_R1=0xa1
SLA_R2=0xa3
;

//-----------------------------
void ERROR (int errcode)
{
if (errorcode == 1 )
UART1_Write_Strf ("fehler beim senden der TWI_STARTCONDITION \n\r");
if (errorcode == 2 )
UART1_Write_Strf ("fehler beim senden der TWI_RSTARTCONDITION \n\r");
if (errorcode == 3 )
UART1_Write_Strf ("fehler beim senden des TWI_SLA_W \n\r");
if (errorcode == 4 )
UART1_Write_Strf ("fehler beim senden des TWI_SLA_R \n\r");
if (errorcode == 5)
UART1_Write_Strf ("fehler während TWI_SENDDATA \n\r");
if (errorcode == 6)
UART1_Write_Strf ("fehler während TWI_RECIVEDATA \n\r");
if (errorcode == 7 )
UART1_Write_Strf ("fehler während TWI_RECIVEDATAF \n\r");
if (errorcode == 8 )
UART1_Write_Strf ("fehler beim senden der TWI_STOPCONDITION \n\r");

}
//------------------------------
void TWI_STARTCONDITION()
{
TWCR=0x00 |(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
while (!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8)!=START)ERROR(1);
}
//------------------------------
void TWI_RSTARTCONDITION()
{
TWCR = 0x00 |(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
while (!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8)!=RSTART)ERROR(2);
}
//------------------------------
void TWI_SLA_W (int SLA_W)
{
TWDR = SLA_W;
TWCR = 0x00 |(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8)!=MT_SLA_ACK)ERROR(3);
}
//------------------------------
void TWI_SLA_R (int SLA_R)
{
TWDR =SLA_R;
TWCR = 0x00 |(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8)!=MR_SLA_ACK)ERROR(4);
}
//------------------------------
void TWI_SENDDATA (int DATA)
{
TWDR=DATA;
TWCR = 0x00 | (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8)!=MT_DATA_ACK)ERROR(5);
}
//------------------------------
char TWI_RECIVEDATA ()
{
char DATA;
TWCR = 0x00 |(1<<TWINT) | (1<<TWEA)| (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8)!=MR_DATA_ACK)ERROR(6);
DATA=TWDR;
return DATA;
}
//------------------------------
//------------------------------
char TWI_RECIVEDATAF ()
{
char DATA;
TWCR = 0x00| (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8)!=MR_DATA_ACK)ERROR(7);
DATA=TWDR;
return DATA;
}
//------------------------------
void TWI_STOPCONDITION()
{
TWCR=0x00 |(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
//while (!(TWCR & (1<<TWINT)));
}

Autor: M. T. (cube7)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Winne,
ich werde mal versuchen mich daran zu orientieren!

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.