Forum: Mikrocontroller und Digitale Elektronik PIC18f2550 i2c. Brauche dringend Hilfe (HDMM01)


von Mathias P. (Firma: HTL - Biomedizin) (cheese_mod)


Lesenswert?

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

von Chris B. (dekatz)


Lesenswert?

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

von Bad U. (bad_urban)


Lesenswert?

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.

von Datenblatt? (Gast)


Lesenswert?

Gibt zu dem IC eigentlich ein erstzunehmendes Datenblatt? Und damit 
meine ich nicht das von Pollin...

von Takao K. (takao_k) Benutzerseite


Lesenswert?

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.

von Chris B. (dekatz)


Lesenswert?

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

von Mathias P. (Firma: HTL - Biomedizin) (cheese_mod)


Lesenswert?

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);

von Max H. (hartl192)


Lesenswert?

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.

von Mathias P. (Firma: HTL - Biomedizin) (cheese_mod)


Lesenswert?

Was bedeutet das für meinen Code? Weiß jemand wie ich das mit dem CCS 
Compiler realisieren kann?

von Mathias P. (Firma: HTL - Biomedizin) (cheese_mod)


Lesenswert?

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();

von Atlas (Gast)


Lesenswert?

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

von Mathias P. (Firma: HTL - Biomedizin) (cheese_mod)


Lesenswert?

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
Noch kein Account? Hier anmelden.