www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIC I2C Fehler mit CCS Compiler in MPLAB


Autor: Michael Wulz (mwulz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

Ich hab MPLAB mit CCS Compiler (MPLAB Version 5).
Ich kann MPLAB leider nicht updaten, da das aktuelle MPLAB Version 8 den 
alten ICD-Programmer/Debugger für die 16F8xx Serie nicht mehr kann.

Da hab ich das Problem, dass der Code bei "i2c_start();" hängen bleibt!
Egal ob ich den ICD-Debugger verwende oder nicht.

Hatte jemand von euch einen solchen Fehler schon mal?

gruss
Michael

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich habe daselbe Problem. das ist mein Code:
void IdleI2C( void )
{
  while ( ( SSPCON2 & 0x1F ) )continue;
}

void StartI2C( void )
{
  SSPCON2bits.SEN = 1;            // initiate bus start condition
  while(SSPCON2bits.SEN);
}
u08 WriteI2C( u08 data_out )
{
  SSPBUF = data_out;           // write single byte to SSPBUF
  if ( SSPCON1bits.WCOL )      // test if write collision occurred
   return ( -1 );              // if WCOL bit is set return negative #
  else
  {
    while( SSPSTATbits.BF );   // wait until write cycle is complete         
    return ( 0 );              // if WCOL bit is not set return non-negative #
  }
}
void StopI2C( void )
{
  SSPCON2bits.PEN = 1;            // initiate bus stop condition
}
 u08 I2C_senden(u08 addr, u08 data)
 {
   IdleI2C();
   StartI2C();
   IdleI2C();
   WriteI2C(addr&0xFE);
   IdleI2C();
   if(SSPCON2bits.ACKSTAT)
   {
     StopI2C();
     return 0;
   }
   WriteI2C(data);
   IdleI2C();
    if(SSPCON2bits.ACKSTAT)
   {
     StopI2C();
     return 0;
   }
   StopI2C();
   return 1;
 }
 
 u08 I2C_lesen(void)
{
  SSPCON2bits.RCEN = 1;           // enable master for 1 byte reception
  while (!SSPSTATbits.BF );      // wait until byte received  
  return ( SSPBUF );              // return with read byte 
}

 

u08 DataRdyI2C( void )
{
  if ( SSPSTATbits.BF )           // test if buffer full bit is set     
    return (1 );                // data in SSPBUF register
  else
    return ( 0 );                 // no data in SSPBUF register
}
u08 recevoir(void)
{ 
  u08 y=0;;
  if(DataRdyI2C())
  {
  y=I2C_lesen();
  if(y==0x45)
  {
    LATDbits.LATD1=1;
    LATDbits.LATD2=0;
  }else{
    LATDbits.LATD2=1;
  LATDbits.LATD1=0;
  }
  }
}
wenn du eine Antwort hat kannst du mir helfen

Autor: Michael Wulz (mwulz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab das Hardware-I2C Modul des PIC 16F877 verwendet.
Mein Code sieht so aus:
#include <16f877.h>
#device ICD=TRUE
#use delay(clock=20000000)
#include <lcd.c>
#use i2c(master, sda=PIN_C4, scl=PIN_C3, noforce_sw)

int i2cT1,i2cT2;

main()
{
  lcd_init();

  i2c_stop();

   while(TRUE)
   {
  i2c_start();
  i2c_write(0b10010001);
  i2cT1=i2c_read();
  i2cT2=i2c_read(0);
  i2c_stop();


   delay_ms(50);

   lcd_gotoxy(1,1);
   printf(lcd_putc,"1:%3u",i2cT1);
   lcd_gotoxy(1,2);
   printf(lcd_putc,"2:%3u",i2cT2);

   delay_ms(500);
   }

}

Bei diesem Code bleibt der Microcontroller immer beim Befehl 
"i2c_start();" hängen. Sieht man im ICD Debugger schön!

Was kann hier der Grund sein?
Ich hab schon nachgesehen, scl und sda Pin's sind mit Pullup auf +5V 
gelegt. Der LM75 Temperatursensor, welcher am I2C Bus hängt hat addresse 
"000" und ich möchte aus diesem Lesen.

Hatte jemand sochon mal sowas?

Michael

Autor: Harald A. (embedded)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei einem Fujitsu Controller hatte ich mal ein ähnliches Problem, der 
Controller blieb blieb hängen, weil die SDA Leitung nicht 
erwartungsgemäß auf High ging. Und das war so:

Es wurde ein I2C EEPROM ausgelesen, bei dem viele Datenzellen auf "0" 
waren. Erwartungsgemäß ist somit beim Auslesen die SDA Leitung relativ 
häufig Low. Sporadisch hing sich das Protokoll auf, auch nach kompletten 
Neustart ging nichts. Es klemmte ebenfalls bei der Erzeugung der 
Start-Condition. Nach längeren Arbeitspausen (ab ca. 20 Minuten) ging es 
dann auf einmal wieder. Auffällig war bei Messungen auf jeden Fall, dass 
das EEPROM seinerseits die Datenleitung auf Low zog. Einfach so, auch 
nach Reset und Trennung der Spannung.
Warum?
Es handelte sich um ein EEPROM, dass auch noch für Spannungen ab 1.8V 
spezifiziert war. Ein EEPROM hat keinen Reset-Eingang, die interne 
State-Machine wird nur bei einem Power-On Reset zurückgesetzt. 
Irgendwann hat es eine Verhakung im Protokoll gegeben und das EEPROM ist 
auf SDA=0 stehengeblieben. Das Ausschalten der Spannung hat nichts 
gebracht, da VCC relativ lange bei ca. 1V stehenbleibt. Das EEPROM war 
selbst bei dieser Spannung noch funktionell. Erst nach langer Zeit fällt 
die Spannung weit unter 1V und das EEPROM machte einen vernünftigen 
Power-On Reset. Daher das Phänomen nach Mittagspause, wo kurzzeitig 
wieder alles funktionierte.

Die Lösung lag darin, nach Power-On des Mikrocontrollers einfach einige 
zig Takte auf SCL manuell zu erzeugen, während SDA=1 bleibt. Dadurch kam 
die State-Machine im EEPROM wieder in den Tritt und der I2C Controller 
im Mikrocontroller fand bei Erzeugung der Start-Bedingung den korrekten 
Zustand SDA=1 vor!

Dieses Phänomen könntet ihr auch mal abchecken, die I2C Start 
Implementierungen bei verschiedenen Controllern sind häufig so 
gestrickt, dass einfach per Endlos-Loop auf SDA=1 (Busfreigabe) gewartet 
wird. Ist bei dieser Abfrage definitiv SDA=1 ???

Autor: Michael Wulz (mwulz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Danke für die Hilfe!

Ich hab's jetzt mit der Software-Variante des CCS Compilers geschafft!

Es gibt hier zwei Möglichkeiten:

einmal um das integrierte i2c Modul zu verwenden
#use i2c(master, sda=PIN_C4, scl=PIN_C3, noforce_sw)

oder
#use i2c(master, sda=PIN_C4, scl=PIN_C3)

Mit der 2ten Variante ohne Hardware Modul läuft es ohne Probleme!
Um auf die software Implementierung zurückzugreifen.

Offensichtlich hat mein LM75 hier ein Problem damit.
Ich werde mal den Tipp mit den SCL Takten versuchen!

danke
Michael

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.