Hallo liebe User, bin gerade echt am verzweifeln :-( Mein Ziel: I²C Kommunikation über MPLab zwischen PIC18F2550 und einer Analog/Digital Input-Karte von Horter. Ich würde gerne analoge Daten von Sensoren einlesen und im Microkontroller anzeigen lassen. Ich habe bisher versucht über eine Step-by-Step Anleitung eine Kommunikation herzustellen (https://electrosome.com/i2c-pic-microcontroller-mplab-xc8/). Den dort zur Verfügung gestellten Quellcode habe ich versucht auf meinen PIC anzupassen (im Tutorial wurde ein anderer PIC verwendet). Genau genommen habe ich nur die Eingangsports für SCL und SDA auf meinen Chip angepasst. Der Code lässt sich auch compilieren. Leider bin ich auf dem Gebiet noch ein blutiger Anfänger. Meine Fragen: 1. Wo kann ich nun die Slave Adresse ansprechen (Ich habe eine Slave Adresse, habe diese jedoch nirgends im Code angesprochen)? 2. Wie mache ich nachdem alle Konfigurationen vorgenommen worden sind weiter? Wie bekomme ich meine Spannungswerte vom Slave eingelesen und in MPLab angezeigt? Zur Hilfe habe ich euch meinen Programmcode einmal kopiert: void I2C_Master_Init(const unsigned long c) { SSPCON1 = 0b00101000; //SSP Module as Master SSPCON2 = 0; SSPADD = (_XTAL_FREQ/(4*c))-1; //Setting Clock Speed SSPSTAT = 0; TRISB1 = 1; //Setting as input as given in datasheet TRISB0 = 1; //Setting as input as given in datasheet } void I2C_Master_Wait() { while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); //Transmit is in progress } void I2C_Master_Start() { I2C_Master_Wait(); SEN = 1; //Initiate start condition } void I2C_Master_RepeatedStart() { I2C_Master_Wait(); RSEN = 1; //Initiate repeated start condition } void I2C_Master_Stop() { I2C_Master_Wait(); PEN = 1; //Initiate stop condition } void I2C_Master_Write(unsigned d) { I2C_Master_Wait(); SSPBUF = d; //Write data to SSPBUF } unsigned short I2C_Master_Read(unsigned short a) { unsigned short temp; I2C_Master_Wait(); RCEN = 1; I2C_Master_Wait(); temp = SSPBUF; //Read data from SSPBUF I2C_Master_Wait(); ACKDT = (a)?0:1; //Acknowledge bit ACKEN = 1; //Acknowledge sequence return temp; } void I2C_Slave_Init(short address) { SSPSTAT = 0x80; SSPADD = address; //Setting address SSPCON1 = 0x36; //As a slave device SSPCON2 = 0x01; TRISB1 = 1; //Setting as input as given in datasheet TRISB0 = 1; //Setting as input as given in datasheet GIE = 1; //Global interrupt enable PEIE = 1; //Peripheral interrupt enable SSPIF = 0; //Clear interrupt flag SSPIE = 1; //Synchronous serial port interrupt enable } void interrupt I2C_Slave_Read() { if(SSPIF == 1) { SSPCON1bits.CKP = 0; if ((SSPCON1bits.SSPOV) || (SSPCON1bits.WCOL)) //If overflow or collision { double z = SSPBUF; // Read the previous value to clear the buffer SSPCON1bits.SSPOV = 0; // Clear the overflow flag SSPCON1bits.WCOL = 0; // Clear the collision bit SSPCON1bits.CKP = 1; } } if(!SSPSTATbits.D_nA && !SSPSTATbits.R_nW) //If last byte was Address + Write { double z = SSPBUF; while(!BF); PORTA = SSPBUF; SSPCON1bits.CKP = 1; } else if(!SSPSTATbits.D_nA && SSPSTATbits.R_nW) //If last byte was Address + Read { double z = SSPBUF; BF = 0; SSPBUF = PORTD ; SSPCON1bits.CKP = 1; while(SSPSTATbits.BF); } SSPIF = 0; } Freue mich über jegliche Anregung :-) Gruß Simon
was ich bräuchte wäre ein Denkanstoß der mich irgendwie weiterbringt ... :)
Also ich versuche es mal, damit du wenigstens eine Antwort kriegst: 1) Wenn du nur einen zusammenkopierten unvollständigen Code hier reinschreibst, und keine Ahnung hast, was überhaupt gemacht werden soll, wird dir niemand helfen. 2) wenn du I2C mit XC8 benutzen willst, nutze doch die plib von Microchip (separater Download + aktivierung in den Linkeroptionen) oder die aktullere Variante: du lässt dir vom Codeconfigurator ein .c/.h-Files erzeugen. 3) In diesem Forum wird dir keiner deine Aufgabe von Grund auf (ohne Bezahlung) machen. Aber wenn du zeigst, dass du etwas gemacht hast, und an einem speziellem Problem hängst, wir dir gerne geholfen. mach folgende Schritte: * Such dir eine Tutorial für PICs * arbeite das durch und lass die ersten LEDs Blinken * Wenn du verstanden hast, was du bis zu diesem Punkt alles gemach hast, such dir im Internet eine Beschreibung zu I2C und verstehe das Protokoll * liess das Datenblatt dieser ominösen "Analog/Digital Input-Karte" und versuch zu verstehen, wie diese über I2C angesteuert werden kann * Versuch das aus dem Datenblatt auf dein PIC umzusetzen Wenn du Fortschritt mit einem kompletten minimalbeispiel zeigst, wirst du auch Antworten bekommen. Mit den Angaben wie aktuell, wird sich keiner die mühe machen.
Michael .. schrieb: > Also ich versuche es mal, damit du wenigstens eine Antwort > kriegst: > > 1) Wenn du nur einen zusammenkopierten unvollständigen Code hier > reinschreibst, und keine Ahnung hast, was überhaupt gemacht werden soll, > wird dir niemand helfen. > > 2) wenn du I2C mit XC8 benutzen willst, nutze doch die plib von > Microchip (separater Download + aktivierung in den Linkeroptionen) oder > die aktullere Variante: du lässt dir vom Codeconfigurator ein > .c/.h-Files erzeugen. > > 3) In diesem Forum wird dir keiner deine Aufgabe von Grund auf (ohne > Bezahlung) machen. Aber wenn du zeigst, dass du etwas gemacht hast, und > an einem speziellem Problem hängst, wir dir gerne geholfen. > > mach folgende Schritte: > * Such dir eine Tutorial für PICs > * arbeite das durch und lass die ersten LEDs Blinken > * Wenn du verstanden hast, was du bis zu diesem Punkt alles gemach hast, > such dir im Internet eine Beschreibung zu I2C und verstehe das Protokoll > * liess das Datenblatt dieser ominösen "Analog/Digital Input-Karte" und > versuch zu verstehen, wie diese über I2C angesteuert werden kann > * Versuch das aus dem Datenblatt auf dein PIC umzusetzen > > Wenn du Fortschritt mit einem kompletten minimalbeispiel zeigst, wirst > du auch Antworten bekommen. Mit den Angaben wie aktuell, wird sich > keiner die mühe machen. Hallo Gismi, Danke für deine Antwort. Der Code Configurator wird auch in einigen tutorials verwendet um die Einstellungen für die I2C Kommunikation zu treffen. Leider wird mein Chip (PIC18F2550) nicht für dieses Plugin unterstützt (Es gibt zwar zusätzliche Bibliotheken für die 18F Familie, jedoch ist in dieser Liste mein Chip nicht dabei --> ich bekomme beim Startversuch eine Fehlermeldung). Habe die Konfiguration der Register und das Ansprechen auch einigermaßen verstanden. Was meinst du damit, die plib von Microchip zu verwenden? Gruß, Simon
Habe mal einen Screenshot der Fehlermeldung angehangen. Kannst du mir genauer sagen, wie ich diese plib einbinden kann?
simon schrieb: > Kannst du mir > genauer sagen, wie ich diese plib einbinden kann? Hier meine abgelegten Notizen dazu: Pblib / plib.h XC8 Folgendes muss gemacht werden • Plib downloaden http://www.microchip.com/mplab/compilers -> Download -> runter scrollen • In den Pfad vom XC8 compiler installieren • Plib linken aktivieren im Installationsverzeichnis hat es entpsrechende Hilfe als pdf
Was für eine XC8 Version hast du installiert? Bis v1.34 müsste die PLib automatisch dabei sein. Spätere Versionen erfordern eine separate Installation. Die Installationsdatei findet sich da, wo auch der XC8 runter geladen werden kann (ganz unten unter "PIC18F Legacy Peripheral Libraries v..." ) Es kann allerdings sein, dass die PLib nicht mehr kompatibel mit deiner XC8 Version ist. Bei einigen PICs wurden Änderungen in den Headern gemacht, welche jetzt Fehler verursachen. Eingebunden wird die Lib dann in den Projekt-Properties. Haken bei "Link in Peripheral Library! (geht bei meinem Projekt nicht, weil kein PIC18)
Volker S. schrieb: > Was für eine XC8 Version hast du installiert? > Bis v1.34 müsste die PLib automatisch dabei sein. Bis wohin plib inkludiert ist wusste ich nicht. Ich glaube es ist v1.38 die ich installiert habe. Da es klang, dass simon frisch mit dem Thema anfängt, bin ich von einer aktuellen Version ausgegangen.
Danke für eure Hilfe! habe die plib.h nun in mein Projekt einbinden können (nutze MPLab X IDE v3.45). Hab noch 2 Fragen: 1. Was bringt mir die zusätzliche Bibliothek eigentlich? 2. Könnt ihr mir einen Tip geben, wo das Einrichten einer I2C Kommunikation gut erklärt wird? Mit dieser (https://electrosome.com/i2c-pic-microcontroller-mplab-xc8/) komme ich nicht so gut zurecht, bzw ich weiß nicht wie ich am Ende wenn ich den Code verstanden und angepasst habe, weiterkomme...
simon schrieb: > habe die plib.h nun in mein Projekt einbinden können Das ist nicht nötig. Wird über xc.h mit erledigt. >(nutze MPLab X IDE v3.45). Hab noch 2 Fragen: Die Version der IDE ist != der Version der Compiler. >1. Was bringt mir die zusätzliche Bibliothek eigentlich? PLib enthält Funktionen für die Benutzung der in Hardware implementierten Module. Schau am besten mal in die Doku MPLAB_XC8_Peripheral_Libraries.pdf Die müsste im docs Ordner des Compilers sein.
Volker S. schrieb: > simon schrieb: >> habe die plib.h nun in mein Projekt einbinden können > Das ist nicht nötig. Wird über xc.h mit erledigt. > >>(nutze MPLab X IDE v3.45). Hab noch 2 Fragen: > Die Version der IDE ist != der Version der Compiler. > >>1. Was bringt mir die zusätzliche Bibliothek eigentlich? > PLib enthält Funktionen für die Benutzung der in Hardware > implementierten Module. Schau am besten mal in die Doku > MPLAB_XC8_Peripheral_Libraries.pdf > Die müsste im docs Ordner des Compilers sein. Sorry habe mich vertan, die Version des Compilers ist v1.38
Hallo nochmal. Ich bin jetzt ein wenig weitergekommen. Leider klappt es immernoch nicht so ganz mit der Kommunikation. Ich habe das Programm darauf im Debug Modus laufen gelassen. Irgendwas stimmt mit dem I2C_Read Befehl nicht. Er hängt sich in einer while-Schleife auf und macht an diesem Punkt nicht weiter (s. Screenshot, SSPSTATbits.BF), er empfängt anscheinend keine Daten. Habt ihr eine Ahnung wodrann das liegen könnte? Wem es hilft dem habe ich außerdem noch meinen Quellcode beigefügt.
1 | void INIT_I2C(void){ |
2 | OpenI2C(MASTER, SLEW_OFF); |
3 | SSPADD = 19; |
4 | }
|
5 | |
6 | |
7 | |
8 | |
9 | unsigned int TEST = 0x0000; |
10 | unsigned char LSB = 0x00, MSB = 0x00; |
11 | |
12 | |
13 | |
14 | while(1) |
15 | |
16 | {
|
17 | |
18 | |
19 | |
20 | StartI2C(); // Start condition I2C on bus |
21 | IdleI2C(); |
22 | |
23 | WriteI2C(0x95); // addresses the chip + 1 LESEN |
24 | IdleI2C(); |
25 | // AckI2C();
|
26 | |
27 | |
28 | |
29 | LSB = ReadI2C(); // read the value from the SLAVE and store in TEST variable. |
30 | IdleI2C(); |
31 | // AckI2C();
|
32 | MSB = ReadI2C(); |
33 | IdleI2C(); |
34 | |
35 | |
36 | // NotAckI2C(); // Not Acknowledge condition. This will signal the SLAVE that reading data has completed.
|
37 | IdleI2C(); |
38 | |
39 | StopI2C(); // Stop condition I2C on bus |
40 | |
41 | |
42 | TEST = MSB << 8 | LSB; |
43 | |
44 | MSB=0x00; |
45 | LSB=0x00; |
46 | }
|
simon schrieb: > Analog/Digital Input-Karte von Horter. Ich würde gerne analoge Daten von > Sensoren einlesen und im Microkontroller anzeigen lassen. Poste doch mal einen Link zu einem Datenblatt. Dann könnten wir da rein schauen um eine Idee zu bekommen was zu tun ist...
Volker S. schrieb: > simon schrieb: >> Analog/Digital Input-Karte von Horter. Ich würde gerne analoge Daten von >> Sensoren einlesen und im Microkontroller anzeigen lassen. > > Poste doch mal einen Link zu einem Datenblatt. Dann könnten wir da rein > schauen um eine Idee zu bekommen was zu tun ist... Beschreibung: http://www.horter.de/blog/i2c-analog-input-5-kanaele-10-bit/ Datenblatt steht leider nicht viel drinn: http://www.horter.de/doku/i2c-hs-analog-input_db.pdf Ich bin mir jedoch nicht sicher ob es was mit den Slave Modulen zutun hat. Denn der I2C_Read Befehl müsste doch auch ohne Slave funktionieren oder (Rückgabewert wäre dann halt random)? Als Pull Up Resistors verwende ich 1,8kOhm. Komisch das er gerade in dieser While-Schleife hängt...
du rufst INIT_I2C() gar nicht auf? bitte poste immer komplette minimalbeispiele
Michael .. schrieb: > du rufst INIT_I2C() gar nicht auf? > > bitte poste immer komplette minimalbeispiele Muss ich die Methode nochmal aufrufen? Ich dachte eigentlich es genügt, durch den Befehl SSPADD = 19; die Baudrate festzulegen.
simon schrieb: > Beschreibung: > > http://www.horter.de/blog/i2c-analog-input-5-kanaele-10-bit/ > > Datenblatt steht leider nicht viel drinn: Dachte mir, dass es sich um diese Teile handelt. Die Doku ist bescheiden. Ich nehme jetzt einfach mal an, du willst immer den selben der 5 input Kanäle lesen und weiterhin, dass der Register-Zeiger innerhalb der Karte bei jedem Lesevorgang um eins erhöht wird. Dann müsstest du den Zieger in der while(1) Schleife immer wieder zurück stellen, also schreiben in das Zeigerregister. Da die Adresse des Zeigerregisters nirgends angegeben wird könnten wir jetzt annehmen, dass jeder Schreibzugriff automatisch auf das Zeigerregister zugreift. FALLS jetzt alle Annahmen zutreffen würden, dann könnte ein Lesezugriff so aussehen:
1 | unsigned int readAdcRegister(unsigned char regAddress) |
2 | {
|
3 | unsigned int value; |
4 | |
5 | IdleI2C1(); |
6 | StartI2C1(); |
7 | while(SSP1CON2bits.SEN); |
8 | |
9 | WriteI2C1(MODUL_ADDRESS_WR); |
10 | while(SSP1CON2bits.ACKSTAT); |
11 | |
12 | WriteI2C1(regAddress); |
13 | while(SSP1CON2bits.ACKSTAT); |
14 | |
15 | RestartI2C1(); |
16 | while(SSP1CON2bits.SEN); |
17 | WriteI2C1(MODUL_ADDRESS_RD); |
18 | while(SSP1CON2bits.ACKSTAT); |
19 | |
20 | value = ReadI2C1(); |
21 | AckI2C1(); |
22 | value += 256 * ReadI2C1(); |
23 | NotAckI2C1(); |
24 | StopI2C1(); |
25 | |
26 | return value; |
27 | }
|
Habe jetzt den Code
1 | OpenI2C(MASTER, SLEW_OFF); |
2 | SSPADD = 19; |
nochmal for die While-Schleife kopiert, funktioniert leider trotzdem nicht
simon schrieb: > Ich bin mir jedoch nicht sicher ob es was mit den Slave Modulen zutun > hat. Denn der I2C_Read Befehl müsste doch auch ohne Slave funktionieren > oder (Rückgabewert wäre dann halt random)? Nein, ohne Slaves geht das nicht. Die müssen ja SDA als ACKnoledge auf Low ziehen...
> { > unsigned int value; > > IdleI2C1(); > StartI2C1(); > while(SSP1CON2bits.SEN); > > WriteI2C1(MODUL_ADDRESS_WR); > while(SSP1CON2bits.ACKSTAT); > > WriteI2C1(regAddress); > while(SSP1CON2bits.ACKSTAT); > > RestartI2C1(); > while(SSP1CON2bits.SEN); > WriteI2C1(MODUL_ADDRESS_RD); > while(SSP1CON2bits.ACKSTAT); > > value = ReadI2C1(); > AckI2C1(); > value += 256 * ReadI2C1(); > NotAckI2C1(); > StopI2C1(); > > return value; > } Hi Volker, danke für deine Umfangreiche Hilfe. Ich habe deinen Quellcode ausprobiert. Leider bekomme ich auch bei diesem Code im Debug Modus den Hänger in der genannten Schleife, wie oben im Screenshot gepostet (SSPSTATbits.BF). Worann kann das liegen das er immer bei diesem Schritt streikt? Der Rest funktioniert (glaube ich :-D )
hallo, versuch doch mal vor der while-schleife SSPBUF = 0; (später wieder entfernen) wenns dann nicht mehr hängt, dann ist das SSPBUF-Register nach der Initialisierung nicht gelöscht worden. Gruss j.p.
liess mal folgende Register aus, wärend er in der Schleife hängt: SSPSTAT SSPCON1 SSPCON2 SSPBUF http://ww1.microchip.com/downloads/en/DeviceDoc/39632e.pdf 19.4 Und wenn du die möglichkeit hast, die Pins SCL/SDA mit einem Oszilloskop oder Logicanalyzer mal aufzeichnen.
:
Bearbeitet durch User
Hallo, war gestern etwas müde, das mit dem SSPBUF = 0; würde nicht klappen. Es ist normal, dass das Programm nicht aus der Schleife kommt, da ja in dieser while-Schleife das Programm darauf wartet, dass das SSPBUF-Register mit einem Daten-byte gefüllt wird. Evtl. könnte man vorübergehend das (!) in der while-schleife entfernen, nur so, um das weitere Programm zu beobachten.... Gruss j.p.
j.p. schrieb: > Evtl. könnte man vorübergehend das (!) in der while-schleife entfernen, Das ist nicht so einfach, weil der Code ja in der Bibliothek schon kompiliert ist. Man muss die Funktion in das Projekt kopieren und da ändern, damit sich das überhaupt auswirkt.
Michael .. schrieb: > liess mal folgende Register aus, wärend er in der Schleife hängt: > SSPSTAT > SSPCON1 > SSPCON2 > SSPBUF > http://ww1.microchip.com/downloads/en/DeviceDoc/39632e.pdf 19.4 > > Und wenn du die möglichkeit hast, die Pins SCL/SDA mit einem Oszilloskop > oder Logicanalyzer mal aufzeichnen. Hello again und danke für eure Geduld mit mir. Die Möglichkeit mit einem Oszi den Bus zu beobachten habe ich leider nicht. Im Anhang habe ich einen Screenshot der ausgelesenen Register angehangen. Selbst wenn ich die Registeradresse um einen Kanal anzusprechen nicht kenne müsste ich ja eigentlich zumindest mal einen Random Kanal auslesen oder? hmm habt ihr noch Ideen was da nicht klappt? :-(
ohne eine Aufzeichnung, wass wirklich auf dem Bus passiert, ist es aus der Ferne extrem schwierig. Für solche sachen habe ich >immer< einen Logicanalyzer in Betrieb. Es gibt schon sehr günstige Modelle. Stell mal die übertragungsfrequenz auf 100kHz. Mit was für einer Frequenz betreibst du den PIC?
Ist denn überhaupt ein Slave (richtig?) angeschlossen? evtl. Foto deiner Schaltung.
@Michael: Übertragungsfrequenz ist bereits auf 100kHz eingestellt PIC-Takt: 8MHz @j.p.: Ich habe neben der o.g. Input Karte einen weiteren Slave angeschlossen, bleibt ebenso im gleichen Schritt hängen. Ich mache heute Nachmittag mal ein Bild der Schaltung, bin gerade auf einer Weiterbildung. Gruß Simon
Hallo, ein häufiger Fehler ist, dass GND von Slave und GND von Master nicht verbunden wurde, wenn beide nicht dieselbe Speisespannung haben....
j.p. schrieb: > Hallo, > ein häufiger Fehler ist, dass GND von Slave und GND von Master nicht > verbunden wurde, wenn beide nicht dieselbe Speisespannung haben.... Ist alles der selbe ground auf einem steckbrett
welchen Programmer/debugger benutzt du? Oder benutzt du nur den blanken Simulator von Mplabx?
j.p. schrieb: > welchen Programmer/debugger benutzt du? > Oder benutzt du nur den blanken Simulator von Mplabx? Ich benutze den ICD 3 Programmer. Im Anhang hab ich euch mal einen Screenshot meiner Schaltung angehangen. Kann man ja "eigentlich" nicht viel falsch machen.
und noch eine Frage: Wie kann es überhaupt sein, dass die Variable "x" (s. Anhang) einen Wert (0x00F2) erhält? Müsste das nicht heißen das die I2C_Read Funktion einen Wert liefert ?
Hallo, deine Schaltung ist etwas abenteuerlich. Womit werden der Master und die Slaves gespiesen? Ich an deiner Stelle würde vorläufig nur einen von beiden Slaves anhängen. Die Slave-Adresse muss natürlich auch stimmen, sonst bleibt die while-Schleife hängen. poste doch mal den komletten Code des pic18f2550 als Anhang. Gruss j.p.
j.p. schrieb: > Hallo, > deine Schaltung ist etwas abenteuerlich. Womit werden der Master und die > Slaves gespiesen? > Ich an deiner Stelle würde vorläufig nur einen von beiden Slaves > anhängen. > Die Slave-Adresse muss natürlich auch stimmen, sonst bleibt die > while-Schleife hängen. > poste doch mal den komletten Code des pic18f2550 als Anhang. > Gruss j.p. Die Speisung der Schaltung ist wie folgt. Master: ICSP Speisung durch ICD3 Slaves: VCC+GND des Mikrocontrollers (Masters) Beide Jeweils von 5V versorgt. Im Anhang der gewünschte Code. Habe die gesamte Projektdatei als Archiv hochgeladen.
Hallo, versuch mal in deinem header.h-file: #pragma config PBADEN = OFF. Gruss j.p.
simon schrieb: > Habe die gesamte Projektdatei als Archiv > hochgeladen. Da ist >90% temporärer Müll drin! Schau dir doch mal das an: Package a Project Into a Zip File http://microchip.wikidot.com/mplabx:projects-package
> #define ADRREAD 0x31 > #define ADRWRITE 0x31 Sollte ADRWRITE nicht 0x30 sein? > RestartI2C(); > while(SSPCON2bits.SEN); > WriteI2C(ADRWRITE); > while(SSPCON2bits.ACKSTAT); > value = ReadI2C(); Lesen sollte man von ADRREAD!
> while(1) > > { > > OpenI2C(MASTER, SLEW_OFF); > SSPADD = 19; Einmal öffnen reicht -> raus aus der Endlosschleife!
Hallo Leute, j.p. schrieb: > Hallo, > versuch mal in deinem header.h-file: #pragma config PBADEN = OFF. > > Gruss j.p. Hab ich gemacht und seitdem kann ich das Programm debuggen OHNE in der genannten Schleife hängen zu bleiben :-) Ein Problem gelöst, danke!! Die Addressen hab ich angepasst, also ADRREAD 0x30 ADRWRITE 0x31 komischerweise funktionieren auch NUR diese Adressen, wenn ich andere Adressen ausprobiere bleibt er beim debuggen hängen. Anscheinend merkt der Debugger, ob man die Slaves mit richtiger Adresse anspricht. Leider bekomme ich noch keine realistichschen Werte eingelesen. Wie ihr auf meinem obigen Schaltungsbild sehen könnt, versuche ich mit einem Poti und Widerstand in Reihe verschiedene Spannung auf die Input Karte zu geben. Nun lese ich in MPLab ALLE Eingänge aus (5*LSB+5*MSB+Zeiger), also 11 Byte. Mache dies, da die Karte nicht gut dokumentiert ist und ich bis jetzt nicht genau weiß wie ich einen der 5 Kanäle anspreche (Adresse unbekannt). Ergebnis: Alle 11 Read-Funktionen liefern den Wert "0x00FF". Eigentlich habe ich erwartet, das zumindest 2 Byte (LSB + MSB) einen Wert analog zur Eingangsspannung ausgeben :-( Pustekuchen...
Hallo Simon, hast du das Poti auch richtig angeschlossen? Bevor du die Poti-Spannung in den ADC des Slaves gibst würde ich diese mit einem Voltmeter über den ganzen Poti-bereich messen, sie darf 2,048 in keiner Stellung des Potis übersteigen, sonst droht die Zerstörung des ADC's....
j.p. schrieb: > Hallo Simon, > hast du das Poti auch richtig angeschlossen? > Bevor du die Poti-Spannung in den ADC des Slaves gibst würde ich diese > mit einem Voltmeter über den ganzen Poti-bereich messen, sie darf 2,048 > in keiner Stellung des Potis übersteigen, sonst droht die Zerstörung des > ADC's.... Jep das hab ich gemacht, habe den Widerstand so dimensioniert das UMax 1,5V beträgt
Bin etwas auf Kriegsfuss mit den Libraries von Microchip, aber beim Betrachten deines Codes glaube ich, dass du die Variable "value" für den low-Bereich des 16-bit-Wertes so wie in deinem Code brauchst, dann aber noch eine Variable z.B. "valueH" für den high-Bereich des 16-bit-Wertes brauchtest, so in etwa: valueH += 256 * ReadI2C(); Was genau in dem ganzen Code vor sich geht kann ich leider nicht beurteilen, da ich die Peripherie-Bibliotheken nicht installiert habe. Gruss
Vergiss was ich geschrieben habe, value ist ja schon 16-bit (int value).
simon schrieb: > Die Addressen hab ich angepasst, also > ADRREAD 0x30 > ADRWRITE 0x31 Sollte das nicht eher umgekehrt sein?
Volker S. schrieb: > simon schrieb: >> Die Addressen hab ich angepasst, also >> ADRREAD 0x30 >> ADRWRITE 0x31 > > Sollte das nicht eher umgekehrt sein? Entschuldigung habe mich vertippt, ja! Ist auch im Code richtig definiert. Echt sehr komisch das sich da nix tut :-( Alle Return Werte der Read-Funtion 0x00FF (komischerweise genau 255 dezimal)... Ich bin jetzt schon seit Tagen an diesem Mist Bus drann :-/ Habe am kommenden Montag einen Termin in meiner Firma, an dem ich die Möglichkeit habe das Bus Protokoll mit einem Oszi anzusehen. Ich hoffe das bringt Klarheit. Bedanke mich bis hierhin nochmal für eure Hilfe heute und die der letzten Tage, mich fasziniert echt der Traffic, den dieses Forum bietet... Zur vervollständigung nochmals der Code bis hierhin :-)
1 | OpenI2C(MASTER, SLEW_OFF); |
2 | SSPADD = 19; |
3 | |
4 | while(1) |
5 | |
6 | {
|
7 | |
8 | int regAddress=0x01; |
9 | unsigned int value=0; |
10 | unsigned int x, LSB, MSB, Zeiger, a, b, c, d, e, f, g, h; |
11 | |
12 | IdleI2C(); |
13 | StartI2C(); |
14 | while(SSPCON2bits.SEN); |
15 | |
16 | WriteI2C(0x30); |
17 | while(SSPCON2bits.ACKSTAT); |
18 | |
19 | // WriteI2C(redAddress);
|
20 | // while(SSPCON2bits.ACKSTAT);
|
21 | |
22 | RestartI2C(); |
23 | while(SSPCON2bits.SEN); |
24 | WriteI2C(0x31); |
25 | while(SSPCON2bits.ACKSTAT); |
26 | |
27 | |
28 | Zeiger = ReadI2C(); |
29 | AckI2C(); |
30 | LSB = ReadI2C(); |
31 | AckI2C(); |
32 | MSB = ReadI2C(); |
33 | value = MSB << 8 | LSB; |
34 | x = value; |
35 | |
36 | NotAckI2C(); |
37 | StopI2C(); |
38 | |
39 | }
|
40 | |
41 | |
42 | return; |
Warum hast du das schreiben der gewünschten Adresse, welche du auslesen willst, auskommentiert? Dann solltest du es besser ganz bleiben lassen.
:
Bearbeitet durch User
simon schrieb: > ( Alle Return Werte > der Read-Funtion 0x00FF (komischerweise genau 255 dezimal)... Da ist nix komisch. Der Bus wird durch die Pullups auf High gezogen, ein ungetriebener Bus liefert also immer Einsen. Und das ist nun mal Hex 0xff. Wer das komisch findet, hat I2C nicht verstanden. MfG Klaus
Vielleicht findet er es nur komisch, dass HB immer 0x00 und LB immer 0xFF sein soll? @Simon: Lies doch mal alle direkt nacheinander. Also Adresse auf Null setzen und dann 11 mal lesen und die Bytes in deine Werte einsortieren. simon schrieb: > Habe am kommenden Montag einen Termin in meiner Firma, an dem ich die > Möglichkeit habe das Bus Protokoll mit einem Oszi anzusehen. Ich hoffe > das bringt Klarheit. Ich weiß gar nicht wie ich ohne Oszilloskop irgendwas entwickeln könnte ;-)
:
Bearbeitet durch User
simon schrieb: > komischerweise funktionieren auch NUR diese Adressen, wenn ich andere > Adressen ausprobiere bleibt er beim debuggen hängen. Anscheinend merkt > der Debugger, ob man die Slaves mit richtiger Adresse anspricht. > Kann das sein das deine Config für den Slave so ist das er auf alle Adressen Reagiert, und dadurch stehen bleibt ? Ansonsten ist die Logic vom MSSP bei I²C recht dumm, Adresse + Daten kommen rein und müssen im Programm gegen gescheckt werden, und dann kannst erst Daten wieder herausschieben. Wie Klaus schon schrieb 0xFF ist ein Zeichen dafür das da nix Rausgeht, eventuell passen die Pullups nicht, aber das kannst ja dann die Tage mal ausmessen.
ES KLAPPT!!!!!!! Zumindest mit einem I2C Temperatursensor. @ Volker: Hab die Register aus dem Grund ausgeklammert, da ich nicht weiß wie die Registeradressen angeordnet sind -> Daher habe ich einfach 11 Bytes ausgelesen (daher auch so viele Variablen oben deklariert) und gehofft den richtigen Ausgang damit auf jedenfall zu messen. Bei dem Temperatursensor funktioniert es einwandfrei, dort kenne ich auch die Registervergabe. Werde jetzt den Hersteller anfragen ob es zu dieser Input Karte auch ein Registerverzeichnis gibt. Vielen Dank
Hallo Simon, na, da hast du aber echt Fortschritte gemacht, gratuliere! Ich denke du wolltest lernen, mit I2-bus umzugehen, sonst könnte man nämlich einfacher, schneller und billiger Sensoren direkt mit dem ADC des PIC18F2550 auslesen und die Resultate z.B. mit dem chipeigenen USB desselben Pics direkt am PC ansehen, Microchip stellt dazu sogar eine VC-USB-Anwendung zur Verfügung. Gruss j.p.
j.p. schrieb: > Hallo Simon, > na, da hast du aber echt Fortschritte gemacht, gratuliere! > Ich denke du wolltest lernen, mit I2-bus umzugehen, sonst könnte man > nämlich einfacher, schneller und billiger Sensoren direkt mit dem ADC > des PIC18F2550 auslesen und die Resultate z.B. mit dem chipeigenen USB > desselben Pics direkt am PC ansehen, Microchip stellt dazu sogar eine > VC-USB-Anwendung zur Verfügung. > Gruss j.p. Ja es ging mir wie du schon sagtest darum, den Bus zu verstehen und zum laufen zu bekommen. Mache gerade das Abschlussprojekt zum staatlich gepr. Elektrotechniker, und da sollen wir zeigen, das wir was draufhaben (oder auch nicht) :-D
simon schrieb: > und da sollen wir zeigen, das wir was draufhaben > (oder auch nicht) :-D für mich komplett durchgefallen. Armutszeugnis für den Techniker-Titel. lg Heiner
Hallo Simon, lass dich ja nicht von Heiner runterkriegen, er ist nicht dein Prüfungsexperte! Viel Erfolg wünscht dir Jochen-Paul
Leider stehen in RLP Mikrocontroller nicht im Lehrplan, obwohl ich das Thema sehr interessant finde....ist daher für mich, genau wie auch das Thema Bus Systeme (kenne die nur auf dem Papier, Strukturen etc) alles Neuland...Fachrichtung Energieelektronik halt :-)
Hallo, ich nutze zum Init eines PIC18F46K80 bei 25MHz folgenden Code
1 | /************************************************************************/
|
2 | // Include-Dateien
|
3 | /************************************************************************/
|
4 | #include <i2c.h> // Include für die I²C Schnittstelle |
5 | /************************************************************************/
|
6 | |
7 | /************************************************************************/
|
8 | // I²C Schnittstelle initialisieren
|
9 | /************************************************************************/
|
10 | void Init_I2C_Master(unsigned short int Takt) |
11 | {
|
12 | TRISDbits.TRISD5 = 1; // SDA-Leitung |
13 | TRISDbits.TRISD6 = 1; // SCL-Leitung |
14 | |
15 | switch (Takt) { |
16 | case 100: SSPADD = 62; // 100 KHz Takt bei 25 MHz |
17 | OpenI2C(MASTER, SLEW_OFF); |
18 | break; |
19 | /************************************************************************/
|
20 | case 400: SSPADD = 15; // 400 KHz Takt bei 25 MHz |
21 | OpenI2C(MASTER, SLEW_ON); |
22 | break; |
23 | }
|
24 | }
|
25 | /************************************************************************/
|
Ich habe ebenfalls die Zusatz-Libary mit eingefügt. Bei den Chips PCF8574, PCF8591 und MCP23017 funktioniert das ganze. Wenn Du willst kann ich Dir die Libarys zusenden. Ingo
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.