Hallo erstmal! Wir haben derzeit ein Projekt am laufen, mit dem Thema Temperaturmessung über I2C mit dem LM75 Baustein. Jedoch hat unser Controller (AT89C52) keinen Integrieren I2C bus. Wir haben also einen I2C-"Simulator" - Source verwendet : http://www.smartdata.com.au/8051/i2c_sw.zip Port1. Jetzt haben wir das Problem, dass das Hinausschrieben auf den Baustein zwar funktioniert, wir jedoch kein ACK vom Sensor bekommen. Sichheitshalber haben wir es mit einem I2C-I/O - Expander probiert, der funktioniert, wissen aber nicht, ob der ein ACK zurücksendet ?! Hat irgendwer eine Idee ? lg HonZ, Nickl
Jeder I2C-Baustein muss auf seine (eingestellte) Adresse ein ACK geben, egal ob ein Schreib- oder Lesezugriff vom Master erfolgen soll. Also ersteinmal nur die Adresse ausgeben und kontrollieren, ob der Slave bestätigt hat. Ohne das ACK geht gar nichts. Gesebdete Adresse kontrollieren, ggf. mehrer ausprobieren, falls mehrere am Slave möglich sind. Jörg
Hi, danke für die Antwort, das ist eben das Problem, wir bekommen kein ACK. Auch mit nur einem Slave, die Adressen stimmen. Ich glaube, dass irgenwie das einlesen vom Port1 am µP nicht funktioniert. Doch wir haben alles versucht, zusätzlich noch einen PullUp geschaltet. Aber keine Chance... lg niki
Schaltung: http://ourworld.compuserve.com/homepages/Dominique_CHARLET/8051.gif (i2c - im Bild links unten) habs auch ohne widerstände versucht.... keine Chance etwas einzulesen... kein ACK, nix... Source: #ifndef READ #define READ 1 #endif #ifndef WRITE #define WRITE 0 #endif #ifndef I2CCLK #define I2CCLK 0xA0 #endif #ifndef SCL static bit SCL @ 0x96; #endif #ifndef SDA static bit SDA @ 0x97; #endif unsigned char _i2c_error; // bit array of error types void _I2CBitDly(void); void _I2CSCLHigh(void); void I2CSendAddr(unsigned char addr, unsigned char rd); void I2CSendByte(unsigned char bt); unsigned char _I2CGetByte(unsigned char lastone); void I2CSendStop(void); #define I2CGetByte() _I2CGetByte(0) #define I2CGetLastByte() _I2CGetByte(1) void _I2CBitDly(void) // wait 4.7uS, or thereabouts { // tune to xtal. This works at 11.0592MHz asm(" NOP"); // delay is 5.4uS, only 4.3uS without return; } void _I2CSCLHigh(void) // set SCL high, and wait for it to go high { register int err; SCL = 1; while (! SCL) { err++; if (!err) { _i2c_error &= 0x02; // SCL stuck, something's holding it down return; } } } void I2CSendAddr(unsigned char addr, unsigned char rd) { SCL = 1; _I2CBitDly(); SDA = 0; // generate start _I2CBitDly(); SCL = 0; _I2CBitDly(); I2CSendByte(addr+rd); // send address byte } void I2CSendByte(unsigned char bt) { register unsigned char i; for (i=0; i<8; i++) { if (bt & 0x80) SDA = 1; // send each bit, MSB first else SDA = 0; _I2CSCLHigh(); _I2CBitDly(); SCL = 0; _I2CBitDly(); bt = bt << 1; } SDA = 1; // listen for ACK _I2CSCLHigh(); _I2CBitDly(); if (SDA) _i2c_error &= 0x01; // ack didn't happen, may be nothing out there SCL = 0; _I2CBitDly(); } unsigned char _I2CGetByte(unsigned char lastone) // lastone == 1 for last byte { register unsigned char i, res; res = 0; for (i=0;i<8;i++) // each bit at a time, MSB first { _I2CSCLHigh(); _I2CBitDly(); res *= 2; if (SDA) res++; SCL = 0; _I2CBitDly(); } SDA = lastone; // send ACK according to 'lastone' _I2CSCLHigh(); _I2CBitDly(); SCL = 0; SDA = 1; _I2CBitDly(); return(res); } void I2CSendStop(void) { SDA = 0; _I2CBitDly(); _I2CSCLHigh(); _I2CBitDly(); SDA = 1; _I2CBitDly(); } // test code //void main(void) //{ // unsigned char b; // I2CSendAddr(1,WRITE); // I2CSendByte(0); // I2CSendStop(); // I2CSendAddr(1,READ); // b = I2CGetByte(); // b = I2CGetLastByte(); // I2CSendStop(); //} /
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.