Forum: Mikrocontroller und Digitale Elektronik ISL29020 - I²C Light Sensor liefert kein ACK?


von H. G. (ledi)


Angehängte Dateien:

Lesenswert?

Hallo,

ich bin gerade dabei, einen I²C Lichtsensor (ISL29020) mit einem 
ATMega88 auszulesen.
Grundsätzlich funktioniert die Kommunikation, aber mein Master sendet 
kein ACK nachdem ein Datensatz mit TWI_READ_DATABYTE_NACK(); gelesen 
wurde!

Wie in den Abbildungen zu sehen, frage ich das Statusregister ab und 
erhalte mit 0x58 ein NACK!

Hat jemand eine Idee, wo der Fehler sein könnte?
1
int main(void)
2
{
3
  DDRD = 0xFF;      // PORTD = output
4
  DDRC = 0x3F;      // PC0 ... PC5 = output
5
  DDRB = 0x03;      // PB0 and PB1 = output
6
  TWBR = BIT_RATE;    // Set the TWI clock-frequency in bit rate register
7
  
8
  TWI_START();      // Send START condition
9
  TWI_MT_SLA_ACK();    // Master Transmit Slave Address with Acknowledge
10
  TWI_MT_DATA_ACK(0x00);  // Transmit 0x00 for Register Command with Acknowledge
11
  TWI_MT_DATA_ACK(0xC3);  // Transmit 0xC3 (1100 1001) EN, Mode=1, Range4
12
  TWI_STOP();        // Send STOP condition
13
  _delay_ms(50);
14
  
15
  while(1)
16
  {
17
    TWI_START();            // Send START condition
18
    TWI_MT_SLA_ACK();          // Master Transmit Slave Address with ACK
19
    TWI_MT_DATA_ACK(0x01);        // Transmit 0x01 to start with Register 0x01 with ACK
20
    TWI_R_START();            // Send REPEATED START condition
21
    TWI_MR_SLA_ACK();          // Send the Slave Address in Master Receive Mode with ACK
22
    LSByte = TWI_READ_DATABYTE_NACK();  // Read one Databyte without ACK
23
    MSByte = TWI_READ_DATABYTE_NACK();  // Read one Databyte without ACK
24
    TWI_STOP();              // Send STOP condition
25
    lux_value = LSByte + MSByte;    // Store 16bit-result in lux_value      
26
  
27
     _delay_ms(200);            // wait 200ms for new readout
28
  }
29
}

von Karl H. (kbuchegg)


Lesenswert?

H. G. schrieb:
> Hallo,
>
> ich bin gerade dabei, einen I²C Lichtsensor (ISL29020) mit einem
> ATMega88 auszulesen.
> Grundsätzlich funktioniert die Kommunikation, aber mein Master sendet
> kein ACK nachdem ein Datensatz mit TWI_READ_DATABYTE_NACK(); gelesen
> wurde!

So recht werde ich aus dem nicht schlau, was du da schreibst.

Im Receive Mode ist doch der Master dafür zuständig NACK oder ACK zu 
generieren. Welches davon der Fall ist, musst du als Programmierer 
vorher festlegen.

Wenn du also eine Funktion namens TWI_READ_DATABYTE_NACK aufrufst, in 
dessen Code auch kein Hinweis darauf zu finden, dass du das TWI Modul 
anweist, dem Client mit einem ACK zu bestätigen, dass du alles gekriegt 
hast, wieso erwartest du das dann?
Und vor allen Dingen, wieso fragst du das in deinem Code ab?
Es geht doch nicht darum, ob der Master einen ACK oder einen NACK als 
Antwort gekriegt hat, sondern er muss dem Client antworten. Der Master 
(im Recieve Mode) muss den ACK oder NACK generieren. Dazu wird das Bit 
TWEA im Register TWCR entsprechend gesetzt.

Entsprechend
1
When the Receiver has received the last byte, or for some reason
2
cannot receive any more bytes, it should inform the Transmitter
3
by sending a NACK after the final byte.
quittiert der Master (im Receive Mode) alle Bytes bis auf das letzte mit 
einem ACK und das letzte Byte wird mit einem NACK quittiert ehe dann der 
Master mittels einer Stop Condition den Bus wieder freigibt. Wenn du 
also von deinem Sensor 2 Datenbytes willst, wird das erste mit einem ACK 
quittiert und das zweite (weil du ja keine weiteren mehr haben willst) 
mit einem NACK.

Eine Abfrage des TWSR bezüglich ACK oder NACK macht an dieser Stelle in 
dieser Funktion überhaupt keinen Sinn.

: Bearbeitet durch User
von H. G. (ledi)


Lesenswert?

Vielen Dank für die konkrete Antwort!
Ich bin da wohl etwas am "Schlauch" gestanden!

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
Noch kein Account? Hier anmelden.