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
Sieht man die Startbedingung und Adresse auf dem Oszilloskop, wenn Master und Slave verbunden sind?
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
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
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
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!
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
Im Silabs Forum hab ich leider nichts Brauchbares gefunden. Ich werde aber zur Sicherheit dort auch etwas posten! Habe 135 in das SMBOCR Register geschrieben, aber es funktioniert trozdem nicht! Hier der Gesamte Code Danke im Vorraus! :)
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.