SMBus0 Kommunikation zwischen zwei 8051 F120 funktioniert nicht

Gast #1948426
Lesenswert?

Hallo

Ich versuche seit geraumer Zeit eine SMBus0 Kommunikation zwischen zwei 
C8051 F120 zu erzielen. Der Master empfängt Daten vom Slave. Da ich nur 
einen Master benötige brauche ich keine Arbitrierung.


Was funktioniert: Der Master: Ich habe mit einem Oszilloskop SDA und SCL 
überprüft, beides funkioniert, Startbedingung wird erzeugt und Adresse 
wird richtig gesendet.

Was nicht funktioniert: Der Slave: Sobald ich Master und Slave verbinde 
tritt sofort ein Bus-Error auf.

Ich kann mir nicht erklären wieso ein Bus Error auftritt, ich hoffe ihr 
könnt mir einige Fehlerquellen nennen.

Danke im Voraus für eure Antworten.

Mfg Berndl
Gast #1949564
Lesenswert?

Nein, Sobald Master und Slave verbunden werden tritt SOFORT ein Bus 
Error auf.
Wenn man nur den Master mit dem Oszilloskop untersucht erzeugt er die 
Startbedingung und sendet die Adresse.

Mfg
Gast #1950260
Lesenswert?

Hallo Bernhard,

wenn nach dem Verbinden der Leitung mit dem Slave kein Signal mehr auf 
der Leitung sichtbar ist, dann zieht der Slave das Signal wahrscheinlich 
auf Ground. Dem Master ist es dadurch nicht möglich etwas zu senden. 
Grund könnten fehlerhafte Porteinstellungen sein.
Miss einfach einmal den Pegel der Portpins des Slaves ohne das ein 
Master angeschlossen ist.

lg Arnold
Gast #1950781
Lesenswert?

Danke für den Tipp,habe es grade gemessen doch  leider ist dies nicht 
die Fehlerquelle da der Pegel auf High Potential liegt.
Habe SCL und SDA über einen Pull-up Widerstand auf +5V angelegt.
Ich bin mittlerweile schon total ratlos was der Fehler sein  könnte.

Mfg
Gast #1959964
Lesenswert?

Ich konnte den Fehler nun weiter eingrenzen. Es sieht nun wie folgend 
aus:

1) Der Master sendet Startbedingung, Slaveadresse und R/W (wobei 1 
(lesen) gesendet wird)
2) Der Slave sendet ein Acknowledge und wechselt dann in den Error 
Zustand. Dadurch wird die Clock Leitung auf Low gezogen. => Der Master 
erkennt dies und wechselt ebenfalls in den Error Zustand.

Zum Testen habe ich die Frequenz des Mikrocontrollers auf 24,5MHz 
gestellt und siehe da, es funktioniert. Das heißt, dass Problem hat mit 
dem Systemclock des Mikrocontrollers zu tun. Dadurch können nur 2 
Codeteile ausschlaggebend sein:
1
void InitController()
2
{
3
  //SFR-Page Einstellungen
4
  /////////////////////////
5
  SFRPAGE = 0x0F;
6
    SFRPGCN = 0x00;  //disables automatic paging
7
  
8
  // Porteinstellungen
9
  /////////////////////                  
10
    XBR2    = 0x40; // Ports auf weak pull-up einstellen und cross-bar 
11
                    // aktivieren
12

13
  //Systemclock (100 MHz)
14
  ////////////////////////
15
    OSCICN =  0x83; //interne Oszillatorfrequenz auf 24.5 MHz
16
  while(!(OSCICN & 0x80)); //Wartet bis die Oszillatorfrequenz stimmt
17
  PLL0CN = 0x00; //Systemclock wird für PLL Eingang benutzt
18
  SFRPAGE = 0;
19
  FLSCL = 0x30; //Flash Read Timing auf 100 MHz geändert
20
  SFRPAGE = 0x0F;
21
  PLL0CN = 0x01; //PLL-Power aktivieren
22
  PLL0DIV = 0x01; //Dividiert den Systemclock (24.5 MHz) durch 1
23
  PLL0FLT = 0x01; //Filtereinstellung: 24.5 MHz Eingang, 100 MHz Ausgang
24
  PLL0MUL = 0x04; //24.5 MHz * 4 = 98 MHz
25
  Sleep(1); //Wait at least 5 µs, to provide a fast frequency lock.
26
  PLL0CN = 0x03; //Aktiviert PLL
27
  while(!(PLL0CN & 0x10)); //Warte bis PLL bereit ist
28
  CLKSEL = 0x02; //Als Systemclock wird nun PLL verwendet  
29
}
1
//Dieses Programm initialisiert den SMBus
2
void SMBus_Init()
3
{
4
  char SFRPAGE_SAVE = SFRPAGE;        // Save Current SFR page
5

6
  SFRPAGE = 0x0F;
7
  P0MDOUT = 0x00; // All P0 pins open-drain output
8
  XBR0 |= 0x01;  // SM-Bus erlauben
9
  P0 = 0xFF;
10
  SFRPAGE = 0x00;
11
  EA=1;
12
  SMB0CN |= 0x04; //SM-Bus erlaubt, Acknowledge aktiviert  
13
  SMB0CR = 256-(((1/SMBUS_CLOCK)*FREQUENZ)/4); //Clockrate  
14
  SMB0ADR = MY_ADDR; //Meine Adresse
15
  SMB0CN |= 0x40; //SM-Bus erlaubt, Acknowledge aktiviert
16
    
17
  SFRPAGE = SFRPAGE_SAVE;
18
}

Hat jemand eine Idee woran das liegen könnte? Das Beispiel von Silabs 
macht es ganz genau so doch so funktioniert es leider nicht... Alle 
Einstellungen stimmen auch mit denen des Datenblattes überein.

PS: SMBUS_CLOCK = 100000, FREQUENZ = 98000000

Danke für eure Hilfe!
Gast #1960431
Lesenswert?

1
SMB0CR = 256-(((1/SMBUS_CLOCK)*FREQUENZ)/4);
Ich komm da auf über 1MHz. Laut SiLabs Example lautet die Formel für 
einen Näherungswert
1
SMB0CR = 257 - (SYSCLK / (8 * SMB_FREQUENCY));
womit ich bei deinen 100kHz Übertragungsrate und einem SysClk von 98MHz 
auf einen CR-Wert von 135 komme.

> Das Beispiel von Silabs macht es ganz genau so doch so funktioniert es
> leider nicht...
Die Aussage ist somit widerlegt (vorausgesetzt, ICH hab jetzt keinen Bug 
gemacht :)

Verwendest du Interrupt oder Polling?
Poste mal den kompletten Code (als Anhang) für den Master und den Slave.

Ansonsten such mal noch hier:
http://www.cygnal.org/scripts/Ultimate.cgi
Das ist das SiLabs Forum.

Ralf
Gast #1962050
Lesenswert?

Hi Bernhard,

bist du weitergekommen? Den Vorschlag von Erik aus dem Cygnal-Forum hast 
du probiert?
Ich hab leider mit I2C auf den SiLabs-Controllern noch nichts gemacht, 
dafür hab ich erst demnächst Verwendung.
Wie stehts denn mit den Beispielprogrammen für den F120? Hast du mal 
probiert das Multimaster-Beispielprogramm runterzuladen?

Ralf
Gast #1967271
Lesenswert?

Hi
Gestern entdeckte mein Kollege den Fehler, beim Slave war im Interrupt 
die falsche SFRPAGE gesetzt. Nach korrigieren dieses Fehlers 
funktionierte die Kommunikation einwandfrei, auch bei 100MHz.

Ich bedanke mich bei euch für eure Ratschläge, Danke! :)

mfg Bernhard B.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren