mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt bei I2C - Startkondition wird nicht ausgelöst


Autor: Tobias John (tobiasjohn) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
mein Problem:
ich nutze das MSSP-Modul eines 16f874 um ein EEPROM zu lesen.
Nun habe ich einige I2C-Routinen ausprobiert und musste leider 
feststellen, dass schon das senden der Start-Condition Probleme 
bereitet.
void i2c_start() {
  SSPIF = 0;
  SEN=1; //Bus-Übernahme anweisen
  while(SSPIF==0); // while(SEN) <== Alternativ
}
Wenn ich while(SSPIF==0) benutze bleibt der PIC an der stelle hängen.
Wenn ich while(SEN) verwende, dann geht es weiter, aber es gibt keine 
Start-Bedingung.

In einer Init-Methode stelle ich die Interrupts ein
GIE = 1; // enable interrupts
PEIE = 1; // enable peripheral interrupts => braucht man wohl nicht, aber habe ich mal mit reingenommen
SSPIE = 1; // enable interrupt for SSPmodule
SSPIF = 0; // CLR SSP-Interrupt-Flag
Die I2C-init-Methode sieht so aus
void i2c_init() {
  TRISC3=1;           // set SCL and SDA pins as inputs
  TRISC4=1;

  SSPADD = 40;//SSPADD_VAL; // Siehe header-datei 100 KHz

  // SSPCON1 - egisters
  SSPCON = 0x28; // Enables Serial Port Mode / I2C Master Mode

  // SSPCON2 - Registers
  SSPCON2 = 0x00;

  // SSPSTAT REGISTERS
  SSPSTAT = 0x80; //   SlewRate Control disabled

  SSPIF = 0; // CLR SSP-Interrupt-Flag
}

und folgendes sende ich in der Main-Methode
i2c_start();
i2c_write( 0xa0 );
i2c_stop();

das ist ja erstmal nicht viel. Ich wollte auch nur testen ob das EEPROM 
ein ACK sendet. Leider tuts das nicht. Es gibt nur ein NACK - Ich denke 
weil die Start-Bedingung fehlt.
Warum sendet der PIC die Start-Bedingung nicht. Bzw. warum wird das 
SSPIF - Flag nicht gesetzt?

Hier mal ein Bild von der Datenübertragung. 
http://img128.imageshack.us/my.php?image=i2cnostar...
(oder siehe Anhang)

Danke schonmal, Tobias

Autor: Tobias John (tobiasjohn) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ähm, Anhang hier :D Sorry

Autor: Tobias John (tobiasjohn) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
ich habe festgestellt, dass wenn ich statt dem Start (SEN = 1) einen 
Restart (RSEN = 1) mache, dann wird die start-bedingung ausgegeben und 
das EEPROM sendet auch ein ACK.
D.h. anscheinend kann der PIC die Pegel (SDA und SCL) nicht richtig 
auswerten. Die Start-Bedingung wird ja nur gesendet wenn SDA und SCL 
high sind. Die Überprüfung fällt bei ReStart weg. Deshalb klappt das mit 
RSEN = 1.

Leider konnte ich trotzdem noch keine Daten empfangen und die Sache mit 
den Interrupts geht immer noch nicht.

Vielleicht kann mir da ja noch jemand helfen.

Gruß,
Tobias

Autor: Tobias John (tobiasjohn) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe herausgefunden, dass der PIC die Start-Bedingung deshalb nicht 
sendet, weil das MSSP-Modul ein Problem mit der Erkennung der Pegel an 
SDA und SCL hat.
Ein schreiben auf dem EEPROM ist interessanter weise möglich. Nur das 
Lesen vom EEprom geht nicht.

Ich habe jetzt eine Software-Variante geschrieben. Mit der geht es.

Vielleicht hat ja jemand noch DEN entscheidenden Tipp für die 
Hardware-Variante.

Danke und Gruß,
 Tobias

Autor: Jens O. (pitcho)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus,
habe gerade das selbe Problem. Der setzt das SSPIF Bit nicht. Der Code 
ist eigentlich der gleich wie der von Tobias:

void  IIC(void)
{
  //Bus übernehmen
  SSPIF = 0;
                SEN = 1;  //Busübernahme anweisen
  while(SSPIF == 0);   //Testen ob Bus übernommen
  SSPIF = 0; //Ja, der Bus ist mein. SSPIF zurücksetzen!

  //Adresse senden
  SSPBUF = 0xA0;  //Adresse Slave
         while(SSPIF == 0);   //Warten bis 9.SCL-Takt
  SSPIF = 0;  //SSPIF zurücksetzen!

  //Datenbyte 1 senden
  SSPBUF = 0x04;              while(SSPIF == 0);   //Warten bis 
9.SCL-Takt
  SSPIF = 0;  //SSPIF zurücksetzen!

  //Datenbyte 2 senden
  SSPBUF = 0x03;              while(SSPIF == 0);  //Warten bis 
9.SCL-Takt
  SSPIF = 0;        //SSPIF zurücksetzen!

  //Bus wieder freigeben
  PEN = 1;                while(SSPIF == 0);  //Warten bis 9.SCL-Takt
  SSPIF = 0;  //SSPIF zurücksetzen!
}


void  INIT_IIC(void)
{
  //Einstellung der IO-Ports
  TRISC = 0b00011000; //1=Eingang, 0=Ausgang
        delay_ms(5);  //5ms Paus

  //Aktivieren des I2C-Interface
  SSPADD = 0x09;  //Busgeschwindigkeit: 0x09 => Fosc = 16 MHz  SSPSTAT = 
0x80;  //Status Register zurücksetzen
  SSPCON1 = 0b00001000; //Bit3-0: 1000 = IIC Master mode
  SSPCON2 = 0b00001000;
         SSPEN = 1;  //I2C-Mode enable
         GIE = 1;            //global interrupt enable
  PEIE = 1; //Peripheral Interrupt Enable bit
  SSPIE = 1;//Master Synchronous Serial Port Interrupt Enable bit


  SSPIF = 0;
}

Autor: Jens O. (pitcho)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, Fehler gefunden. Lag an den Interrupts.

Autor: Pic16f (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich weiß die Diskussion ist schon sehr alt, aber was war die 
genaue Lösung für das Problem?

Danke

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.