Forum: Mikrocontroller und Digitale Elektronik I2C mit Codesys


von Peulebo (Gast)


Angehängte Dateien:

Lesenswert?

Hallo, ich programmiere zur Zeit eine I2C Kommunikation. Den Master 
(BECK sc24 Mikrocontroller)habe ich mit Codesys programmiert. Der Slave 
ist ein Atmega32, der von mir in C programmiert wurde. Ich habe den 
Slave mit Interrupts programmiert. Master Transmitter--> Slave receiver 
funktioniert soweit, kann man im Anhang sehen.
Jetzt zu meinem Problem, die Funktion Slave Transmitter-->Master 
receiver funktioniert leider nicht, um genau zu sein wird immer ein nack 
angezeigt. Kann man im Anhang auf dem Screenshot vom Logikport sehen.
Vielleicht sieht jemand was im c Code falsch ist oder ergänzt werden 
muss.

#include<avr/interrupt.h>
#include<util/twi.h>
#include<avr/io.h>
#include<util/delay.h>


ISR(TWI_vect)
{
  switch(TWSR)
  {
    //SR - Slave Receiver

    case 0x60: //Der Slave erkennt seine Adresse und erhält die SLA+W 
Anweisung des Masters. Daraufhin bestätigt er mit ACK
      TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);
    break;

    case 0x80: //Der explizit adressierte Slave empfängt das  vom Master 
gesendete Datenbyte und bestätigt durch ACK.
      TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);
    break;     //Dies wird solange wiederholt, bis die STOP-Bedingung 
eintrifft.

    case 0xA0: //STOP-Bedingung wurde erkannt
      TWCR=0;
      TWCR=(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTO);
      TWCR=(1<<TWEN)|(1<<TWIE)|(1<<TWEA);
    break;

    //ST - Slave Transmitter

    case 0xA8: //Der Slave erkennt seine Adresse und die SLA+R Anweisung 
und bestätigt durch ACK.
      TWCR=(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTO);
      TWCR=(1<<TWEN)|(1<<TWIE)|(1<<TWEA);

    case 0xB8: //Das in TWDR gespeicherte Byte wurde übertragen und ACK 
wurde vom Master empfangen.
      TWDR = 0b11110000;
      TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);

    break;

    case 0xC0: //Das in TWDR gespeicherte Byte ist das letzte das 
übertragen wurde.
           //Der Master hat dies erkannt und bestätigt durch NACK.
    break;
    default:
      while(1)
      {
        asm volatile ("nop");
      }
    break;
  }
}


int main ()
{
  sei();
  TWAR=(48<<1)|0;
  TWBR=32;
  TWSR=0;
  TWCR=0;
  TWCR=(1<<TWEN)|(1<<TWIE)|(1<<TWEA);

  while(1)
  {
    asm volatile ("nop");
  }
}

von Peulebo (Gast)


Lesenswert?

#include<avr/interrupt.h>
#include<util/twi.h>
#include<avr/io.h>
#include<util/delay.h>

ISR(TWI_vect)
{
  switch(TWSR)
  {
    //SR - Slave Receiver

    case 0x60: //Der Slave erkennt seine Adresse und erhält die SLA+W 
Anweisung des Masters. Daraufhin bestätigt er mit ACK
      TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);
    break;

    case 0x80: //Der explizit adressierte Slave empfängt das  vom Master 
gesendete Datenbyte und bestätigt durch ACK.
        TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);
    break;

    case 0xA0: //STOP-Bedingung wurde erkannt
      TWCR&=~((1<<TWSTO)|(1<<TWSTA));
      TWCR=(1<<TWEN)|(1<<TWIE)|(1<<TWEA)|(1<<TWINT);
    break;

    //ST - Slave Transmitter
    case 0xa8:
      TWCR=0;
      TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);

    case 0xb8:
      TWDR=200;
      TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);
    break;

    case 0xc8:

    break;
      while(1)
      {
        asm volatile ("nop");
      }
    break;
  }
}


int main ()
{
  TWAR= (48<<1)|0;; //Adresse setzen
  TWCR &= ~(1<<TWSTA)|(1<<TWSTO);
  TWCR|= (1<<TWEA)|(1<<TWEN)|(1<<TWIE);
  TWDR=0;
  sei();


  while(1)
  {
    asm volatile ("nop");
  }
}

Habe den Code nochmals etwas verkürzt, habe leider immer noch das 
Problem das Slave Transmitter Master --> Receiver nicht funktioniert.

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.