Forum: Mikrocontroller und Digitale Elektronik Erneute Frage zu TWI (Code)


von Martin K. (thereallife)


Lesenswert?

Moin moin alle zusammen,
erstmal nochmal ein Danke an alle die mir gestern geholfen haben die 
Thematik zu verstehen, ich habs jetzt glaube ich endlich geblickt.

Ich hab jetzt nen Code für den Master und für den Slave geschrieben, 
scheinbar hängt es aber an einer stelle,

Ok So ist mein Aufbau:
2 Atmega ein Master ein Slave.
SDA und SCL sind miteinander verbunden, die Leitungen gehen über jeweils 
einen Widerstand an VCC

Was passiert:
Die Verbindung scheint zu "abzubrechen" scheinbar hab ich irgendeinen 
Fehler im Code so das Master und Slave auseinanderlaufen?! bzw sich 
einfach unterbrechen...

den Master hab ich mit TX und RX an den Arduino, somit kann ich mir ne 
monitor ausgabe geben.

Wenn ich den Slave neu programmiere, kommt dort die ganze Zeit
Kann nix vom Bus lesen
Kann auf den Bus nicht schreiben
Was ja auch klar ist wenn der Slave nicht da ist.
Wenn der Slave wieder da ist, gibt es eine aktion,
Entweder
gelesenes Byte : 30,
oder
20 wurde gesendet

beide richtig, mit dem Slave sende ich testeshalber ne 30 rüber und der 
master sendet eine 20.

Hier mal der Code, eventuell habt ihr ja auch tipps wie ich das ganze 
debuggen kann um den Fehler zu finden.
Meine Kommentare könnt ihr Ignorieren, Sie waren nur für mich da um mir 
das ganze mehr einzuprägen.
Außer in der TWIMaster_Stop funktion da wäre es interessant ob das so 
richtig ist, oder so wie im Kommentar steht ;)
1
while (TWCR & (1<<TWINT)); // müsste das nicht while(!(TWCR & (1<<TWINT) sein?



Master Main
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#ifndef F_CPU
4
#define F_CPU 8000000L
5
#endif
6
#include <stdio.h>
7
#include <util/delay.h>
8
#include <string.h>
9
//#include "ShiftOut.h"
10
//#include "ShiftIn.h"
11
#include "UART.h"
12
#include "TWIInclude.h"
13
// #include "Encoder.h"
14
#define LED1    PD2
15
#define LED2    PD3
16
#define LED3    PD4
17
#define LED4    PD5
18
#define LED5    PD6
19
#define LED6    PD7
20
#define LED_DDR    DDRD
21
#define LED_PORT  PORTD
22
23
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
24
25
int main (void)
26
{
27
  uint8_t    i;
28
  uint8_t    j=0;
29
  uint8_t    Data[8];
30
  uint8_t    SlaveAddresse = 50;
31
  cli ();
32
  stdout = &mystdout;
33
  long baud = 9600UL;
34
  UART_Init(baud);
35
  LED_DDR = (_BV(LED1)) | (_BV(LED2)) | (_BV(LED3)) | (_BV(LED4)) | (_BV(LED5)) | (_BV(LED6));
36
  if (!TWIMaster_Init (100000))
37
  {
38
    printf ("Fehler beim Initialisieren des TWI Interfaces");
39
    while(1);
40
    {
41
      //
42
    }
43
  }
44
  LED_PORT ^= ( 1 << LED1 ); // LEd 1 An wenn bis hier alles funzt
45
  while(1)
46
  {
47
      if (!TWIMaster_Start (SlaveAddresse, TWIM_READ))
48
      {
49
        TWIMaster_Stop();
50
        printf("Kann nix vom Bus lesen\n");
51
        LED_PORT ^= ( 1 << LED2 );  
52
      }
53
      else
54
      {
55
        Data[1] = TWIMaster_ReadNack ();
56
        printf ("gelesenes Byte : %d, \n", Data[1]);
57
        LED_PORT ^= (1<<LED3);
58
      }
59
      if (!TWIMaster_Start (SlaveAddresse, TWIM_WRITE))
60
      {
61
        TWIMaster_Stop();
62
        printf ("Kann auf den Bus nicht schreiben\n");
63
        LED_PORT ^= ( 1 << LED4 ); 
64
      }
65
      else
66
      {
67
        TWIMaster_Write(20);
68
        printf("20 wurde gesendet\n");
69
        TWIMaster_Stop();
70
        LED_PORT ^= ( 1 << LED5); 
71
      }
72
  }
73
  return 0;
74
}

Master Funktionen C-Datei
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#ifndef F_CPU
4
#define F_CPU 8000000L
5
#endif
6
#include <stdio.h>
7
#include <util/delay.h>
8
#include <string.h>
9
10
#define FALSE            0
11
#define TRUE            1
12
#define TWI_START          0x08  // 00001000 // START has been transmitted
13
#define TWI_REP_START        0x10  // 00010000 // Repeated START has been transmitted
14
#define TWI_MTX_ADR_ACK        0x18  // 00011000 // SLA+W has been tramsmitted and ACK received
15
#define TWI_MRX_ADR_ACK        0x40  // 01000000 // SLA+R has been tramsmitted and ACK received
16
#define TWI_MTX_DATA_ACK      0x28  // 00101000 // Data byte has been tramsmitted and ACK received
17
18
uint8_t TWIMaster_Init (uint32_t TWI_Bitrate)
19
{
20
  TWBR = ((F_CPU/TWI_Bitrate)-16)/2;
21
  if (TWBR < 11) 
22
  {
23
    return FALSE;
24
  }
25
}
26
27
uint8_t TWIMaster_Start (uint8_t Adresse, uint8_t TWIMaster_Typ)
28
{
29
  uint8_t twst;
30
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // TWI Interrupt // TWI Start Condition Bit // TWI Enable Blit 
31
  //TWint löscht den Flag, TWSTA sagt master möchte auf den Bus zugreifen // TWEN = schaltet TWI an
32
  while(!(TWCR & (1<<TWINT))); // Es wird darauf gewartet das TWI die änderung übernommen hat
33
  twst = TWSR & 0xF8; // 11111000 in twst steht nun die ersten 5 Bits
34
  if ((twst != TWI_START) && ( twst != TWI_REP_START))
35
  {
36
    return FALSE;
37
  }
38
  TWDR = (Adresse<<1) + TWIMaster_Typ; // beschreibt das TWDR Register
39
  TWCR = (1<<TWINT) | (1<<TWEN); // schreibt Daten raus
40
  while (!(TWCR & (1<<TWINT))); // Wartet darauf das die übertragung abgeschlossen ist
41
  twst = TWSR & 0xF8;
42
  if ((twst != TWI_MTX_ADR_ACK) && (twst != TWI_MRX_ADR_ACK))
43
  {
44
    return FALSE;
45
  }
46
  return TRUE;
47
}
48
49
uint8_t TWIMaster_Stop (void)
50
{
51
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
52
  // TWINT flag gelöscht // TWEN Enable TWI // TWSTO - TWI Stop Condition 
53
  while (TWCR & (1<<TWINT)); // müsste das nicht while(!(TWCR & (1<<TWINT) sein?
54
}
55
56
uint8_t TWIMaster_Write(uint8_t byte)
57
{
58
  uint8_t twst;
59
  TWDR = byte;
60
  TWCR = (1<<TWINT) | (1<<TWEN);
61
  while (!(TWCR & (1<<TWINT)));
62
  twst = TWSR & 0xF8;
63
  if (twst != TWI_MTX_DATA_ACK)
64
  {
65
    return 1;
66
  }
67
  return 0;
68
}
69
70
uint8_t TWIMaster_ReadNack (void)
71
{
72
  TWCR = (1<<TWINT) | (1<<TWEN);
73
  while(!(TWCR & (1<<TWINT)));
74
  return TWDR;
75
}

Master Include.h
1
#define TWIM_READ    1
2
#define TWIM_WRITE   0
3
4
uint8_t TWIMaster_Init (uint32_t);
5
uint8_t TWIMaster_Start (uint8_t , uint8_t);
6
uint8_t TWIMaster_Stop (void);
7
uint8_t TWIMaster_Write(uint8_t);

Slave Main Datei
1
#define LED1    PD2
2
#define LED2    PD3
3
#define LED3    PD4
4
#define LED4    PD5
5
#define LED5    PD6
6
#define LED6    PD7
7
#define LED_DDR    DDRD
8
#define LED_PORT  PORTD
9
10
#include <avr/io.h>
11
#include <stdio.h>
12
#include <avr/interrupt.h>
13
14
#ifndef F_CPU
15
#define F_CPU 8000000L
16
#endif
17
18
#include <stdio.h>
19
#include <util/delay.h>
20
#include <string.h>
21
#include "TWISlave.h"
22
#include "UART.h"
23
24
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
25
26
int main (void)
27
{
28
  uint8_t i=0;
29
  uint8_t j=0;
30
  uint8_t byte[8];
31
  uint8_t TWIS_ResonseType;
32
  cli();
33
  stdout = &mystdout;
34
  long baud = 9600L;
35
  UART_Init(baud);
36
  TWISlave_Init(50, 100000);
37
  printf("Hallo\n");
38
  LED_DDR = (_BV(LED1)) | (_BV(LED2)) |(_BV(LED3)) | (_BV(LED4));
39
  LED_PORT = _BV(LED1);
40
  while (1)
41
  {
42
    if (TWISlave_ResonseRequired(&TWIS_ResonseType))
43
    {
44
      switch (TWIS_ResonseType)
45
      {
46
        case TWISlave_ReadBytes:
47
            LED_PORT ^= _BV(LED2);
48
            byte[7] = TWISlave_ReadNack();
49
            printf ("Byte gelesen: %d\n", byte[7]);
50
            TWISlave_Stop();
51
          break;
52
        case TWISlave_RESTART:
53
            LED_PORT = _BV(LED4);
54
            TWISlave_Write(50);
55
            printf("Repeat Start wurde ausgeführt\n");
56
            TWISlave_Stop();
57
          break;  
58
        case TWISlave_WriteBytes:
59
            LED_PORT ^= _BV(LED3);
60
            TWISlave_Write(30);
61
            TWISlave_Stop();
62
          break;
63
      }
64
    }
65
    i++;// wozu hier das i++?
66
  }
67
  return 0;
68
}

Slave Funktion C-Datei
1
#include <stdio.h>
2
#include <avr/interrupt.h>
3
#ifndef F_CPU
4
#define F_CPU 8000000L
5
#endif
6
7
uint8_t TWISlave_Init(uint8_t Adresse, uint32_t Bitrate)
8
{
9
  TWBR = ((F_CPU/Bitrate)-16)/2;
10
  if (TWBR < 11) 
11
  {
12
    return 0;
13
  }
14
  TWAR = (Adresse << 1);
15
  TWCR = (1<<TWEN) | (1<<TWEA); 
16
  return 1;
17
}
18
19
uint8_t TWISlave_ResonseRequired(uint8_t * TWI_ResonseType)
20
{
21
  *TWI_ResonseType = TWSR; 
22
  return TWCR & (1<<TWINT); 
23
}
24
25
uint8_t TWISlave_ReadAck(void)
26
{
27
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
28
  while (!(TWCR & (1<<TWINT)));
29
  return TWDR;  
30
}
31
32
uint8_t TWISlave_ReadNack (void)
33
{
34
  TWCR = (1<<TWINT) | (1<<TWEN);
35
  while (!(TWCR & (1<<TWINT)));
36
  return TWDR;
37
}
38
39
uint8_t TWISlave_Stop()
40
{
41
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO) | (1<<TWEA);
42
}
43
44
TWISlave_Write(uint8_t byte)
45
{
46
  TWDR = byte; 
47
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
48
  while (!(TWCR & (1<<TWINT)));
49
}

Slave Include:
1
#ifndef _TWISlave
2
#define _TWISlave
3
4
#define TWISlave_RESTART       0xA0
5
#define  TWISlave_ReadBytes    0x60
6
#define  TWISlave_WriteBytes    0xA8
7
8
uint8_t TWISlave_Init(uint8_t, uint32_t);
9
uint8_t TWISlave_ResonseRequired(uint8_t *);
10
uint8_t TWISlave_ReadAck(void);
11
uint8_t TWISlave_ReadNack(void);
12
void TWISlave_Stop(void);
13
void TWISlave_Write(uint8_t);
14
15
#endif

Danke!

von Martin K. (thereallife)


Lesenswert?

ok, das eine TWIMaster_Stop() was ihm Read aufruf gefehlt hab, hab ich 
hinzugefügt.

Ich hab auch schon bereits ausprobiert ob eins von den beiden für sich 
funktioniert,
Weder der Write noch der Read aufruf stoppen noch einer übertragung.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Du solltest das etwas strukturierter angehen. Als I²C-Neuling 
gleichzeitig Master und Slave programmieren zu wollen, funktioniert nur 
mit sehr sehr viel Glück :-)

a) besorg dir einen "Hardware-Slave", also irgendeinen Sensor oder was 
immer, welches per I2C angesprochen wird, und wo du dich einigermaßen 
drauf verlassen kannst dass er funktioniert.

b) besorg dir einen I2C-Master für den PC (ich nutze hierfür das geniale 
Teil vom Till Harbaum: 
http://www.harbaum.org/till/i2c_tiny_usb/index.shtml) um a) wirklich 
ganz ganz fest abzusichern (es gibt nix frustrierenderes als 
stundenlanges Fehler suchen im eigenen I2C-Master Code, um dran 
draufzukommen dass der Slave kaputt ist... been there, seen it :-(


dann machst du dich erstmal an den Master. Aber auch hier strukturiert.

1. erzeuge ein Start-Condition, und prüfen den Status. Dieser sollte 
0x08 "A START condition has been transmitted" sein (für Details bitte 
Datenblatt fragen, ich rede hier immer vom ATmega328P). Wenn nicht, ist 
schon was faul, und du brauchst nicht weiterzumachen.

2. sende ein SLA+R an eine nicht existente Adresse, und prüfe den 
Status. Dieser sollte 0x48 "SLA+R has been transmitted; NOT ACK has been 
received" sein. Wenn nicht, ist was faul, und du brauchst nicht 
weiterzumachen.

3. sende ein SLA+R an eine sehr wohl existente Adresse (Sensor aus Punkt 
a von oben), und prüfe den Status. Dieser sollte 0x40 "SLA+R has been 
transmitted; ACK has been received" sein. Wenn nicht, ist was faul, und 
du brauchst nicht weiterzumachen.

Wenn du mal soweit gekommen bist, hast du schon den größten Schritt 
erfolgreich erledigt: Du hast beim Slave "angerufen" und der hat den 
Hörer abgenommen und "ja bitte?" geantwortet. Dann meld dich nochmal, 
dann sehen wir weiter (ich hab jetzt keine zeit den ganzen Rest 
aufzuschreiben)

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Im Übrigen ist Schritt 2 und 3 von oben der Schlüssel zum Verständnis 
von I2C (zumindest wars bei mir so): Ein Paket besteht immer aus 9 Bits: 
8 Datenbits, und das ACK/NAK. Der Trick ist nun: Die Datenbits werden 
immer vom Transmitter erzeugt (das muss nicht der Master sein!), das 
ACK/NACK aber vom Receiver. Der Receiver empfängt die 8 Bits, und 
erzeugt er im selben Paket noch schnell das 9te Bit. Am Transmitter 
umgekehrt: Er sendet 8 bits, und lauscht noch kurz auf der 9te bit. Das 
heisst aber auch für die Software: Zwischen Empfang eines Pakets und 
Senden des ACK oder NAK hast du keine Möglichkeit zu reagieren, oder 
anders gesagt: schon bevor du das Paket empfängst, musst du der 
TWI-Hardware sagen, ob sie den nächsten Empfang mit ACK oder NAK 
quittieren soll!

Ein Spezialfall ist noch die Reaktion auf ein SLA+RW: Streng genommen 
"empfängt" der master kein NAK wenn keiner antwortet, die 
Statusbeschreibung "SLA+R has been transmitted; NOT ACK has been 
received" ist insofern irreführend, als das nciht wirklich ein NAK 
empfangen wird, weil auch niemand ein NAK sendet. NAK bedeutet in diesem 
Fall einfach ein Ausbleiben das ACK, elektrisch gesehen bleibt die 
SDA-Leitung auf high, weil sie keiner auf Low zieht.

von Martin K. (thereallife)


Lesenswert?

Ich habe ein funktionierendes gegenstück,
ich hab zwar ein paar Schritte übersprungen, allerdings funktioniert der 
Master am Arduino ohne Probleme,

Verbinde ich Master mit Arduino und packe auf den Arduino folgende 
Software:
1
// Wire Slave Receiver
2
// by Nicholas Zambetti <http://www.zambetti.com>
3
4
// Demonstrates use of the Wire library
5
// Receives data as an I2C/TWI slave device
6
// Refer to the "Wire Master Writer" example for use with this
7
8
// Created 29 March 2006
9
10
// This example code is in the public domain.
11
12
13
#include <Wire.h>
14
15
void setup()
16
{
17
  Wire.begin(50);                // join i2c bus with address #4
18
  Wire.onReceive(receiveEvent);
19
  Wire.onRequest(requestEvent); // register event
20
  Serial.begin(9600);           // start serial for output
21
}
22
23
void loop()
24
{
25
}
26
27
// function that executes whenever data is received from master
28
// this function is registered as an event, see setup()
29
void receiveEvent(int howMany)
30
{
31
  while(1 < Wire.available()) // loop through all but the last
32
  {
33
    char c = Wire.read(); // receive byte as a character
34
    Serial.print(c);         // print the character
35
  }
36
  int x = Wire.read();    // receive byte as an integer
37
  Serial.println(x);         // print the integer
38
}
39
40
void requestEvent()
41
{
42
  Wire.write(50); // respond with message of 6 bytes
43
                       // as expected by master
44
}
In meinem Atmega Log steht fröhlich
gelesenes Byte : 50,
20 wurde gesendet
(in endlos ausführung) ;)
und in meinem Arduino werden die Daten auch ausgegeben

(ich sollte vill erwähnen, ich hab hier 2 arduinos,
einmal den mega2560 der master bzw slave spielt. und ein Arduino Uno in 
dil variante, wo der prozessor abgezogen ist und nur tx,rx und masse 
verbunden sind. Der 2te arduino dient mir als monitor ausgabe für den 
Atmega

wenn ich den Arduino mit dem Slave verbinde und dem Arduino folgenden 
Code gebe:
1
#include <Wire.h>
2
3
void setup()
4
{
5
  Wire.begin();        // join i2c bus (address optional for master)
6
  Serial.begin(9600);  // start serial for output
7
}
8
int x = 40;
9
void loop()
10
{
11
  Wire.requestFrom(50, 1);    // request 6 bytes from slave device #2
12
13
  while(Wire.available())    // slave may send less than requested
14
  { 
15
    char c = Wire.read(); // receive a byte as character
16
    Serial.print(c);         // print the character
17
  }
18
    int y = Wire.read(); // receive a byte as character
19
    Serial.print(y);
20
      Wire.beginTransmission(50); // transmit to device #4
21
    Wire.write(x);              // sends one byte  
22
    Wire.endTransmission();    // stop transmitting
23
}
läuft laut meines Atmega Monitors alles super:

byte geschrieben
Byte gelesen: 40

40 ist richtig,

was mir dabei aber grade aufgefallen ist (und das auch nur durch zufall 
weil der Arduino Monitor noch offen war)
ist der Arduino Master und ließt werte ein, kommt da nur -1 an ?! das 
ist mir vorher noch nicht aufgefallen weil ich dummerweise nur auf das 
TX lämpchen geschaut habe und gesehn hab ok er schickt was raus.

Denn fehler im Code vom Slave beim schreiben konnte ich allerdings nicht 
ausfindig machen...

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Nachdem du meinen rat, das ganze strukturiert anzugehen, ignorierst 
(oder erst gar nicht gelesen) hast, und stattdessen weiter einfach 
wahllos Code aus dem Internet per Copy&Paste zusammenwürfelst, dabei 
auch noch munter nativen AVR und Arduiono-Code mischst, bin ich raus. 
ich wünsch dir noch viel Erfolg.

von Martin K. (thereallife)


Lesenswert?

Michael Reinelt schrieb:
> 1. erzeuge ein Start-Condition, und prüfen den Status. Dieser sollte
> 0x08 "A START condition has been transmitted" sein (für Details bitte
> Datenblatt fragen, ich rede hier immer vom ATmega328P). Wenn nicht, ist
> schon was faul, und du brauchst nicht weiterzumachen.
>
> 2. sende ein SLA+R an eine nicht existente Adresse, und prüfe den
> Status. Dieser sollte 0x48 "SLA+R has been transmitted; NOT ACK has been
> received" sein. Wenn nicht, ist was faul, und du brauchst nicht
> weiterzumachen.

Vielleicht hätte ich erwähnen sollen, das ich
  if (TWSR == 0x48)
  {
    LED_PORT = _BV(LED5);
    while(1)
    {
      _delay_ms(200);
      LED_PORT ^= ( 1 << LED4 );
    }
in meine TWIMaster_Start Routine reingepackt habe...
natürlich habe ich auch das ganze mal mit einer falschen adresse 
ausprobiert. Dann springt er auch in diese schleife.

Michael Reinelt schrieb:
> 3. sende ein SLA+R an eine sehr wohl existente Adresse (Sensor aus Punkt
> a von oben), und prüfe den Status. Dieser sollte 0x40 "SLA+R has been
> transmitted; ACK has been received" sein. Wenn nicht, ist was faul, und
> du brauchst nicht weiterzumachen.

gut das habe ich übersprungen.

I²C funktioniert meines wissens überall gleich, warum also keinen 
Arduino nehmen? Ich möchte halt weiterkommen und nicht 2 tage warten bis 
die entsprechende Hardware da ist.


mag auch gut sein das ich von einer Libary abgeschrieben habe. 
Allerdings nur von einer und diesen Code habe ich 3 mal abgeschrieben 
und mir kommentare & gedanken dazu gemacht. Anfangs und das hast du 
gestern gesehen, habe ich mir fragen aufgeschrieben weil ich nicht 
wusste was die einzelnen Register bedeuten. Als ich die Register 
beschreibung im Datenblatt gefunden habe. hab ich mir alles auf DINA4 
blätter geschrieben und hier im Zimmer aufgeghangen damit ich 
nachschauen kann. Anschließend bin ich nochmal durch den gesamten code 
gegangen und hab alles verstanden und mir nur als komentar 
hingeschrieben was genau passiert und bis auf die eine Zeile die ich 
oben hingeschrieben habe. Habe ich alles verstanden. Ich mag noch ein 
Noob sein was die ganze mpu geschichte angeht, aber ich mach hier 
bestimmt kein copy und paste.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Martin Kathke schrieb:
> Vielleicht hätte ich erwähnen sollen, das ich [das] in meine TWIMaster_Start 
Routine reingepackt habe...
Ja hättest du :-)

Martin Kathke schrieb:
> natürlich habe ich auch das ganze mal mit einer falschen adresse
> ausprobiert. Dann springt er auch in diese schleife.

Gut.

Martin Kathke schrieb:
> gut das habe ich übersprungen.

schlecht. Dann hol das bitte nach.

Martin Kathke schrieb:
> I²C funktioniert meines wissens überall gleich, warum also keinen
> Arduino nehmen? Ich möchte halt weiterkommen und nicht 2 tage warten bis
> die entsprechende Hardware da ist.

Aber du kannst nicht sicher sein dass der Arduino-Slave funktioniert. 
Solange ist das Glaskugel-Lesen, auf das hier keiner Lust hat. Aber 
versuch trotzdem mal, ob du wenigstens ein ACK kriegst.

von Martin K. (thereallife)


Lesenswert?

if (TWSR == 0x40)
  {
    LED_PORT = _BV(LED6);
  }

hatte ich erst drin,
da ging die led nicht an,
dann ist mir aufgefallen das er wenn ich starte meistens nur einmal 
schreibt und dann stopt
also hab ich
  if (TWSR == 0x18)
  {
    LED_PORT = _BV(LED6);
  }

draus gemacht und die LED6 geht an ;)

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Martin Kathke schrieb:
> if (TWSR == 0x18)

und was heisst 0x18? (bin grad etwas offline)

von Martin K. (thereallife)


Lesenswert?

0x18 SLA+W has been tramsmitted and ACK received

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.