Hallo Mikrocontroller Community! Ich bin grade dabei mein Maturaprojekt fertig zu stellen und brauche deshalb dringend Hilfe. Ich versuche die Daten des Magnetfeldsensors über i2c mit dem PIC18f2550 einzulesen aber kenne mich überhaupt nicht mit i2c aus. Im Datenblatt steht dass die Adresse des Bauteils 60H ist. Bit 0 für Messung, Bit 1 für SET und Bit 2 für Reset. Hier der Link http://www.pollin.de/shop/downloads/D810164B.PDF Wie sieht nun die Reihenfolge für die Befehle aus? Ich programmiere mit dem CCS Compiler mit MPLAB. Auf was muss ich des weiteren besonders achten? Ich hoffe jemand kann mit weiter helfen. Derzeitiger Code: i2c_start(); // Starten des I2C Bussystems i2c_write(0x60); mag = i2c_read(0); // Lesen des letzten Bytes mit keinem Acknowledge-Bit (0) i2c_stop(); // Stoppen des Bussystems delay_ms(100); printf(usb_putc,"\fakt. Winkel:\n%d Grad",mag); // Ausgabe des Wertes auf dem Terminal
Das im Link ist zwar ein BASCOM Programm - aber der Ablauf um den Sensor auszulesen dürfte sich leicht in C umsetzen lassen. http://www.mtahlers.de/index.php/elektronik/sensoren/mmc2120mg
Ich kenne mich mit dem CSS-Compiler leider nicht aus. Aber der Code erinnert mich an die I2C-Funktionen der Plib des XC8. Du musst nach jedem Schreiben des Schieberegisters warten bis alles rausgetaket ist. Dafür gibts eine Wait-Funktion. Vielleicht ist das Warten auch schon in den einzelnen Funktionen mit drin. Kann ich nicht sagen. Ich benutze meine eigenen I2C Funktionen, daher kann ich da nicht mehr auskunft geben. Debugge es doch einfach mal im Einzelschritt. Wenns zeitliche Probleme sind bekommst du das dann raus. Oder einfach im Code das WCOL bit abfragen.
Gibt zu dem IC eigentlich ein erstzunehmendes Datenblatt? Und damit meine ich nicht das von Pollin...
http://www.mtahlers.de/index.php/elektronik/sensoren/mmc2120mg Dein I2C code ist unvollstaendig. Schau dir mal microchip PDF an fuer serial EEPROM, oder DS1307. Im Microchip PDF ist das I2C protokoll im Detail erklaert.
Das ist nicht "mein" Code und es ging bei der Frage des TE wohl eher darum, wie der Messablauf ist. Mit der Kentniss wie man I2C EEPROMS anspricht kommt er auch nicht viel weiter. Ein DB für den Sensor gibt es hier: http://www.datasheetdir.com/MMC2120MG+Magnetic-Field-Sensors
So vielen Dank für die Hilfe. Hab es mit dem Link probiert und das ist jetzt mein Code. Funktioniert aber leider noch immer nicht. Kann mir noch jemand weiterhelfen? //set/reset coil i2c_start(); // Starten des I2C Bussystems i2c_write(0x60); i2c_write(0x00); i2c_write(0b00000010); i2c_stop(); delay_ms(1); //Messung i2c_start(); i2c_write(0x60); i2c_write(0x00); i2c_write(0x01); i2c_stop(); delay_ms(5); i2c_start(); i2c_write(0x60); i2c_write(0x00); i2c_start(); i2c_write(0x61); //lesen for(i = 1; i<=5; i++){ i2c_read(1); i2c_read(Dat[i]); } i2c_read(Dat[5]); //kein ACK i2c_stop(); //oberes nibble löschen Dat[2] = Dat[2] && 0b00001111; Dat[4] = Dat[4] && 0b00001111; //x- und y- wert berechnen x = Dat[2] * 256; x = Dat[3]; y = Dat[4] * 256; y = y + Dat[3]; delay_ms(40); printf(usb_putc,"\fakt. x - Winkel:\n%d Grad",x); // Ausgabe des Wertes auf dem Display printf(usb_putc,"\fakt. y - Winkel:\n%d Grad",y);
Mathias Polz schrieb: > for(i = 1; i<=5; i++){ > > i2c_read(1); > i2c_read(Dat[i]); > } > > i2c_read(Dat[5]); //kein ACK > i2c_stop(); Du musst das ACK und NACK senden.
Was bedeutet das für meinen Code? Weiß jemand wie ich das mit dem CCS Compiler realisieren kann?
Okay ich denke das war ein peinlicher Codefehler. Das Ergebnis sieht aber ebenso falsch aus. Als Ausgabe für x und y immer 0. Geändert: for(i = 1; i<=5; i++){ Dat[i] = i2c_read(1); } Dat[5] = i2c_read(); //kein ACK i2c_stop();
Habe vor 2 Jahren mit dem Modul und einem PIC 18F4525 rumgespielt. Hier mein damaliger Code allerdings in Assembler. Was mir bei Deinem Code aufgefallen ist, dass Du vor dem I2C-Lesen ein "I2C-Start" sendest. Hier müsste ein "I2C-Repeated Start" erfolgen. Das ist nicht das Gleiche. ;********************************************************************** HDMM01_MESS ; initiate an complete measurement sequence CALL HDMM01_RESET ; RESET sequence CALL HDMM01_SET ; SET sequence CALL HDMM01_TM ; take measurement MOVLW D'10' CALL DEL_VAR1ms CALL HDMM01_RD ; read data RETURN ;********************************************************************** HDMM01_RESET ; RESET coil CALL i2c_on ; Set Start MOVLW H'60' ; 0110 0000 CALL i2c_tx ; HDMM01 zum Schreiben adressieren MOVLW H'00' ; send HDMM01 Address byte CALL i2c_tx ; MOVLW H'04' ; send HDMM01 RESET-Comand CALL i2c_tx ; CALL i2c_off MOVLW D'15' CALL DEL_VAR1ms RETURN HDMM01_SET ; SET coil CALL i2c_on ; Set Start MOVLW H'60' ; 0110 0000 CALL i2c_tx ; HDMM01 zum Schreiben adressieren MOVLW H'00' ; send HDMM01 Address byte CALL i2c_tx ; MOVLW H'02' ; send HDMM01 SET-Comand CALL i2c_tx ; CALL i2c_off MOVLW D'55' CALL DEL_VAR1ms RETURN ;********************************************************************** HDMM01_TM CALL i2c_on ; Set Start MOVLW H'60' ; 0110 0000 CALL i2c_tx ; HDMM01 zum Schreiben adressieren MOVLW H'00' ; send HDMM01 Address byte CALL i2c_tx ; MOVLW H'01' ; send HDMM01 Data byte "TM-Comand" CALL i2c_tx ; CALL i2c_off RETURN HDMM01_RD ; CALL i2c_on ; Set Start MOVLW H'60' ; 0110 0000 CALL i2c_tx ; HDMM01 zum Schreiben adressieren MOVLW H'00' ; send HDMM01 Address byte CALL i2c_tx ; CALL i2c_rsen ; Repeat Start MOVLW H'61' ; 0110 0001 CALL i2c_tx ; HDMM01 zum Lesen adressieren CALL i2c_rxack MOVFF SSPBUF,H'400' ; store "Internal register" MOVF SSPBUF,W CALL RS232out CALL i2c_rxack MOVFF SSPBUF,H'401' ; store "MSB X-axis" MOVF SSPBUF,W CALL RS232out CALL i2c_rxack MOVFF SSPBUF,H'402' ; store "LSB X-axis" MOVF SSPBUF,W CALL RS232out CALL i2c_rxack MOVFF SSPBUF,H'403' ; store "MSB Y-axis" MOVF SSPBUF,W CALL RS232out CALL i2c_rx MOVFF SSPBUF,H'404' ; store "LSB Y-axis" MOVF SSPBUF,W CALL RS232out CALL i2c_notack CALL i2c_off RETURN
Okay ich habe den Fehler gefunden. Da das delay vom Quarz abhängig ist, waren die 1ms bei 4MHz viel zu klein. Jetzt funktioniert es mit 48ms Wartezeit. Vielen Dank für eure Hilfe, ihr habt mir mein Maturaprojekt gerettet :D
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.