Forum: Mikrocontroller und Digitale Elektronik ADXL345 I2C PIC18


von Mario (Gast)


Lesenswert?

Ich möchte gerne den ADXL345 mit meinem PIC18F45K22 über I2C ansprechen. 
Ich verwende den C18 Compiler. Ich habe noch nie mit I2C gearbeitet, 
aber mit SPI schon eine wenig Erfahrung gesammelt. Ich kann den Sensor 
nicht mit SPI ansprechen, da der SDO bei meinem Breakoutboard auf Masse 
ist. Da ich die viele Dinge oft am besten mit Beispielen lerne möchte 
ich fragen, ob jemand einen Code für den C18 Compiler um den ADXL345 
anzusprechen hat?

von Mario (Gast)


Lesenswert?

Hat jemand einen Code?

von Mario (Gast)


Lesenswert?

???

von Mario (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt ein bisschen probiert, und habe folgenden Code 
geschrieben. Wenn ich alles richtig verstanden habe müsste der ADXL 
jetzt dauernd Messungen ausführen. Ich kann mit dem Oszi am 
Interrupt-Pin aber nichts messen. Wo könnte der Fehler liegen.
Anbei ist noch der Schaltplan der Platine.
Könnte es ein Problem sein, dass der PIC mit 5V versorgt wird, der ADXL 
aber nur mit 3,3V?
1
  LATC=0x00;
2
  TRISC=0xFF;
3
  ANSELC=0x00;
4
5
  OpenI2C1(MASTER, SLEW_ON);
6
7
  IdleI2C1();  
8
  StartI2C1();
9
  WriteI2C1(0xA6);    // Write
10
  WriteI2C1(0x31);    // Data Format    
11
  WriteI2C1(0x0B);    // +/-16g, 13-BIT    
12
  StopI2C1();  
13
  
14
  IdleI2C1();
15
  StartI2C1();
16
  WriteI2C1(0xA6);    // Write    
17
  WriteI2C1(0x2D);    // POWER_CTL    
18
  WriteI2C1(0x08);    // START MEASUREMENT    
19
  StopI2C1();
20
    
21
  IdleI2C1();
22
  StartI2C1();
23
  WriteI2C1(0xA6);    // Write
24
  WriteI2C1(0x2E);    // INT_ENABLE
25
  WriteI2C1(0x80);    // ENABLE DATA_READ INTERRUPT
26
  StopI2C1();

von Tach (Gast)


Lesenswert?

Mario schrieb:
> Könnte es ein Problem sein, dass der PIC mit 5V versorgt wird, der ADXL
> aber nur mit 3,3V?

Normalerweise nicht, solange der uC NICHT 5V treibt.
Also nur als Open-Collector arbeitet.

Wie sieht es auf der Daten/Clock-Leitung aus?
Kommt da das raus was Du erwartest?

von Mario (Gast)


Angehängte Dateien:

Lesenswert?

Die Signale sehen so aus.
Kann es sein, dass sie Pullups zu groß sind?

von Stampede (Gast)


Lesenswert?

Die Pullups sind viel zu groß, gehe mal auf so 1k5 bis 2k2, je nach dem 
was du da hast.

von Mario (Gast)


Lesenswert?

Ich habe leider keine 0603 Widerstände zu Hause.
Müsste der Code aber in Ordnung sein??

von Tach (Gast)


Lesenswert?

Was für eine SCLK-Frequenz hast Du eingestellt?
Wie hast Du das Bild oben gemessen?
Tastkopf?
Evtl. noch eine Bandbreitenbeschränkung im Oszi eingestellt?
Wie lang sind die Leitungen zwischen ADXL und PIC?

von Tach (Gast)


Lesenswert?

Tach schrieb:
> Was für eine SCLK-Frequenz hast Du eingestellt?

Bzw. besser: Was für eine SCLK-Frequenz misst Du mit dem Oszi?

von Tach (Gast)


Lesenswert?

Im Datenblatt S.10 steht die Adresse für Write übrigens mit 0x3A und für 
Read 0x3B.
Das kann ich bei Dir auch nicht erkennen!?

von Tach (Gast)


Lesenswert?

Tach schrieb:
> Im Datenblatt S.10 steht die Adresse für Write übrigens mit 0x3A und für
> Read 0x3B.

Ok, habs selbst gesehen. Ist der Widerstand auch bestückt?

von Mario (Gast)


Lesenswert?

Ja, alles ist bestückt.

von Mario (Gast)


Lesenswert?

Tach schrieb:
> Bzw. besser: Was für eine SCLK-Frequenz misst Du mit dem Oszi?

Die Frequenz ist laut Oszi ca. 600kHz

von Tach (Gast)


Lesenswert?

Mario schrieb:
> Die Frequenz ist laut Oszi ca. 600kHz

Laut Datenblatt ist für den Sensor 100kHz bis max. 400kHz !!! erlaubt.
Wahrscheinlich bekommt der Sensor es garnicht richtig mit was Du von Ihm 
haben möchtest.
Das Oszibild ist leider sehr schlecht zu interpretieren was das ACK vom 
Sensor angeht.
Stell den Takt mal Testweise auf 100kHz runter und versuche es nochmal.

Grüße

von Mario (Gast)


Angehängte Dateien:

Lesenswert?

Jetzt ist der Takt ca. 90 kHz. An den Interrupt Pins bekomme ich aber 
immer noch kein Signal...

von Tach (Gast)


Lesenswert?

Es kommt aber schonmal ein ACK zurück ;-)

von Tach (Gast)


Lesenswert?

Was für einen Pegel haben denn die INT Ausgänge?

von Tach (Gast)


Lesenswert?

Schreib mal in das Register 0x2F (Interrupt MAP ) eine 0x7F rein.
Evtl. bleibt der PIN immer auf einem Pegel, da ja alle Interrupts 
verodert auf einem PIN sind. Also evtl. ist immer einer aktiv und 
deshalb bleibt er auf einem Level.

von Mario (Gast)


Lesenswert?

Tach schrieb:
> Schreib mal in das Register 0x2F (Interrupt MAP ) eine 0x7F rein.
> Evtl. bleibt der PIN immer auf einem Pegel, da ja alle Interrupts
> verodert auf einem PIN sind. Also evtl. ist immer einer aktiv und
> deshalb bleibt er auf einem Level.

Das habe ich gemacht.

INT 1 ist 1
INT 2 ist 0

Muss ich die Interupt Flag-Bits wider löschen?

von Karol B. (johnpatcher)


Lesenswert?

Mario schrieb:
> Jetzt ist der Takt ca. 90 kHz.

Wieso eigentlich ca. 90 kHz? Ich bin zwar mit PICs nicht wirklich 
vertraut, aber das Datenblatt verrät, dass der o.g. Controller durchaus 
über ein entsprechendes Hardware-Modul verfügt. Insofern sollte es kein 
Problem sein, da "echte" 100 kHz hinzubekommen.

Nicht, dass das jetzt deine Probleme "löst", aber besonders sauber 
erscheint mir ja deine Vorgehensweise nicht zu sein, da "irgendwas" zu 
nehmen und z.B. mit 600 kHz anzufangen. Im Standard-Mode sind halt 100 
kHz üblich, und stellen i.d.R. auch kein Problem dar.

von Tach (Gast)


Lesenswert?

Mario schrieb:
> Muss ich die Interupt Flag-Bits wider löschen?

Keine Ahnung, musst Du nachlesen. Wahrscheinlich schon.
Ich leg mich jetzt mal ein bischen in die Sonne ;-)

von Mario (Gast)


Lesenswert?

Karol Babioch schrieb:
> Wieso eigentlich ca. 90 kHz?

http://ww1.microchip.com/downloads/en/appnotes/00735a.pdf
Ich habe die Formel auf S.3 verwendet und dann das Ergebniss (49 bei 
20MHZ) in das SSPADD-Register geschrieben.

von Mario (Gast)


Lesenswert?

Stimmt die Leseroutine so?
1
      IdleI2C1();
2
      StartI2C1();
3
      WriteI2C1(0xA6);    // Write  
4
      WriteI2C1(0x30);    // INT_SOURCE
5
      StopI2C1();
6
      StartI2C1();    
7
      WriteI2C1(0xA7);    // Read
8
      read=ReadI2C1();
9
      NotAckI2C1();
10
      StopI2C1();  
11
      PORTD=read;

von Karol B. (johnpatcher)


Lesenswert?

Mario schrieb:
> http://ww1.microchip.com/downloads/en/appnotes/00735a.pdf
> Ich habe die Formel auf S.3 verwendet und dann das Ergebniss (49 bei
> 20MHZ) in das SSPADD-Register geschrieben.

Und mit welchen Werten hast du gerechnet? Du musst ja den Wert für die 
Frequenz des I2C Busses einsetzen. Für 16 MHz Taktfrequenz und 100 kHz 
erhalte ich 39.

von Mario (Gast)


Lesenswert?

Karol Babioch schrieb:
> Für 16 MHz Taktfrequenz und 100 kHz
> erhalte ich 39.
Ich auch. Nur läuft mein PIC mit 20MHz und bei 20MHz erhalte ich 49.

Stimmt der Code zum lesen von Registern?

von Der Rächer der Transistormorde (Gast)


Lesenswert?

Mario schrieb:
> Ich möchte gerne den ADXL345 mit meinem PIC18F45K22 über I2C ansprechen.

hier

http://www.mikroe.com/mikromedia/pic18fj/

findest du eine sehr gut dokumentierte und funktionierende (selbst 
getestet) Beispielapplikation mit Code Schaltplan und allem was man 
sonst so braucht.

Ist aber für den PIC18F87J50.

von Mario (Gast)


Lesenswert?

Das Auslesen der Werte für die Beschleunigung habe ich jetzt geschafft.
Ich weiß nur noch nicht, wie ich das Interrupt-Flag lösche. Dazu habe 
ich in Datenblatt nichts gefunden.

von Mario (Gast)


Lesenswert?

Das mit dem Interrupt flag habe ich jetzt auch gefunden.

Danke für euere Hilfe!

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.