Forum: Mikrocontroller und Digitale Elektronik AVR Tempeatursensor auslesen SPI


von Uwe (Gast)


Lesenswert?

Hallo,

ich versuche gerade einen Temperatursensor per SPI auszulesen. SPI 
funktioniert anscheinend prinzipiell. Ich konte mir einen kleinen 
LogicAnalyzer leihen und zumindest mal überprüfen, ob Die Clock und CS 
richtig läuft. Ich habe nun nur das Problem, dass mir der 
Temperatursensor immer die gleichen Werte ausgibt.

Ich lese zwei mal acht Bit aus. Die Werte sind immer gleich, egal wie 
warm oder kalt es ist. Die Werte sind immer 0x02 und 0x04.
Die Clock läuft Ordnungsgemäß und CS eben auch, sonst würde ja auch gar 
nix ausgelesen.

Der Sensor ist übrigens ein ADT7301.

Hat jemand eine Idee, woran das liegen könnte?

Vielen Dank!
Gruß
Uwe

von Daniel H. (Gast)


Lesenswert?

Mit Hellsehen habens die meisten hier nicht so...
Tönt als würdest du mit der SPI was falsch machen... Hard- oder Soft 
SPI???

poste doch mal Schema + Software sonst wirds schwirig dazu was zu 
sagen...

von Werner (Gast)


Lesenswert?

Uwe schrieb:
> Die Clock läuft Ordnungsgemäß und CS eben auch, sonst würde ja auch gar
> nix ausgelesen.

Das ist kein Argument. Wenn du nicht den richtigen SPI Mode gesetzt 
hast, kann es übles Kuddel Muddel geben.

Wenn du das Programm postest, schreib doch auch bitte gleich, welchen 
Prozessor du verwendest und mit welcher Taktfrequenz du ihn betreibst.

von Uwe (Gast)


Lesenswert?

Hallo,

ich verwende einen AT90CAN32; 16MHz

Hardware SPI.

Hier einmal die SPI Init:
1
void init(void)                
2
{
3
    SPI_PORT_DDR &=~(1<<SPI_MISO);           // miso auf input
4
    SPI_PORT_DDR |= (1<<SPI_Clock);          // clock auf output
5
    SPI_PORT_DDR |= (1<<SPI_MOSI);           // mosi auf output
6
    SPI_PORT_DDR |= (1<<SPI_SS);            
7
    DDRA |= (1<<PE2); 
8
    PORTE |= (1<<PE2);      // CS auf High                               
9
                                           
10
                                           
11
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<CPOL)|(1<<CPHA);    
12
              // SPI Enable
13
              // Master Select
14
              // f_clkio/64
15
              // Leading Edge -> Falling
16
              // Trailing Edge -> Rising

Hier folgt das Auslesen:
1
int main(void)
2
{
3
       cli();                       
4
       init();                  
5
sei();                       
6
     
7
    volatile uint16_t data;
8
9
    PORTE &= ~(1<<PE2);                // CS 
10
    _delay_us(10);                          
11
    SPDR= 0x00; 
12
    while(!(SPSR & (1<<SPIF)));             
13
    data= (SPDR<<8);                                         
14
    SPDR= 0x00;                             
15
    while(!(SPSR & (1<<SPIF)));             
16
    data+= SPDR;                            
17
    _delay_us(10);                           
18
    PORTE |= (1<<PE2);                   
19
20
    while(1)
21
    {
22
        ...
23
    }
24
}
Vielen Dank!
Gruß
Uwe

von Uwe (Gast)


Lesenswert?

Hallo,

ich habe mittlerweise vorsichtshalber mal einen anderen Temperatursensor 
genommen, um auszuschließen, dass der eine kaputt ist oder so. Es ergibt 
sich aber das gleiche Bild. Es kommen Daten, aber nix gescheites.

Vielen Dank!
Gruß
Uwe

von Uwe (Gast)


Lesenswert?

> data= (SPDR<<8)

Bin kein C-Experte, aber wenn SPDR 8bit sein sollte, ist dann nicht ein 
Cast erforderlich, damit die Bits nicht einfach verschwinden?

data = ((uint16_t)SPDR)<<8 ?

von Uwe (Gast)


Lesenswert?

Hallo,

> data= (SPDR<<8)

Das dürfte auch so gehen. Ich konnte mir mittlerweile mal ein gescheites 
Oszi ausleihen. Damit kontrolliere ich die empfangenen Daten. Der Sensor 
spuckt immer 0x02 0x04 raus, egal welche Temperatur das ist. Wenn ich 
das im Code debugge, steht das auch so in den Variablen drin, d.h. dass, 
was vom Sensor gesendet wird, wird auch richtig empfangen. Nur die 
Daten, die der Sensor sendet sind irgendwie Müll, aber ich habe keine 
Ahnung, woran das liegen könnte. Wie oben geschrieben, habe ich den 
Sensor ja schon getauscht.

Vielen Dank!
Gruß
Uwe

von Datenblatt-Leser (Gast)


Lesenswert?

Die Timing-Characteristics aus dem Datenblatt richtig umgesetzt
?

von Uwe (Gast)


Lesenswert?

Hallo,

ich hoffe ja.

Usprünglich hatte ich mal mit folgendem angefangen
1
                                       
2
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<CPOL)|(1<<CPHA);    
3
              // SPI Enable
4
              // Master Select
5
              // f_clkio/64
6
              // Leading Edge -> Falling
7
              // Trailing Edge -> Rising

(1<<CPOL) und (1<<CPHA) habe ich jetzt mal weggelassen, aber das 
Ergebnis ist das selbe.
Ich habe verschiede Geschwindigkeiten probiert, aber auch das selbe 
Ergebnis.

Ich sehe es schon kommen, das hängt wieder nur an einer super 
Kleinigkeit.

Vielen Dank!
Gruß
Uwe

von Karl H. (kbuchegg)


Lesenswert?

Überprüf nochmal die Edge Einstellung.

Wenn ich das Datenblatt richtig lese, dann liegt das Datenbit nach der 
steigenden Flanke korrekt an.


(Zur Not würde ich das mal nicht mit Hardware sondern mit Software SPI 
probieren. Das bischen Pinwackeln ist ja nicht das grosse Problem. Aber 
Soft-SPI kann ich so langsam machen wie ich will. Zb auch so langsam, 
dass ich mit einer LED den Zustand der Datenleitung sehen kann :-)

von Uwe (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe jetzt noch einmal mit den Einstellungen des SPI gespielt.

Ich habe einmal die Edge Einstellung geändert, das ändert aber leider 
nichts an meinem Ergebnis. Ich habe mal einen Screenshot vom SPI Signal 
angehängt.

Das ist mit den folgenden Einsellungen entstanden:
1
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); // f_clkio/128 bei 16MHz

Software SPI werde ich dann wohl mal als nächstes probieren. Mal sehen, 
ob es damit geht.

Vielen Dank!
Gruß
Uwe

von Uwe (Gast)


Lesenswert?

Hallo,

jetzt weiß ich gar nicht mehr weiter.
 Ich habe jetzt einmal die lock per Software getoggelt und den 
Datenstrom mit einem Analyzer überwacht. Die Clock läuft wunderbar, CS 
ebenfalls, der Sensor spuckt Daten aus, aber wie oben 02h 04h. Das 
einzige, was anders ist, ist, das die Pause zwischen den beiden Byte 
Daten nicht vokommt, wenn ich die Clock per Software toggeln lasse.

In diesem Moment sende ich nix an den Sensor. Das verlangt der ja auch 
nicht.

Das verstehe wer will.

Vielen Dank!
Gruß
Uwe

von eProfi (Gast)


Lesenswert?

Zuerst das Datenblatt:
http://www.analog.com/static/imported-files/data_sheets/ADT7301.pdf
Es wäre Deine Aufgabe gewesen, den Link zu posten.

Die Frage ist: wie hast Du Din (Pin 2) angeschlossen?
Wenn der auf H-Pegel liegt, geht das Device in den Stand-By-Mode, was 
eine solche Antwort erklären könnte.

von Matthias (Gast)


Lesenswert?

Uwe schrieb:
> Ich habe mal einen Screenshot vom SPI Signal angehängt.

Verglichen mit dem Datenblatt (Figure 14. Serial Interface Timing 
Diagram)
ist dein Clock genau invertiert.
http://www.analog.com/static/imported-files/Data_Sheets/ADT7301.pdf

von Michael (Gast)


Lesenswert?

Bin gard nur mit dem iPad unterwegs aber mir scheint, dass mit dem Clock 
alles ok ist, ne Invertierung seh ich grad nicht, liegt aber vielleicht 
auch am Gerät.
Da aber immer das gleiche Signal kommt könnte ich mir auch eher sowas 
wie Stand By vorstellen.

von eProfi (Gast)


Lesenswert?

0x204 sind 16,125°C.

Beim Auslesen der Daten wird immer gleichzeitig ins Config-Register 
geschrieben.

An sich ein schickes Teil (1/32 ° Auflösung), was kosten die und wo gibt 
es die?

Matthias hat Recht, der Ruhepegel von Clk sollte H sein.
Mit den 2 Bits CPOL und CPHA gibt es ja 4 Möglichkeiten (die schon 
manchen Entwickler zum Verzweifeln brachten), aufpassen: manchmal geht 
eine Richtung, aber die andere nicht, oder die Übertragung ist 
unzuverlässig, wenn diese Bits nicht stimmen.


SUPPLY DECOUPLING
The ADT7301 should be decoupled with a 0.1 μF ceramic capacitor between 
VDD and GND. This is particularly important if the ADT7301 mount is 
remote from the power supply.

von Matthias (Gast)


Lesenswert?

Michael schrieb:
> Bin gard nur mit dem iPad unterwegs aber mir scheint, dass mit dem Clock
> alles ok ist, ne Invertierung seh ich grad nicht, liegt aber vielleicht
> auch am Gerät.

In dem Datenblatt liegt SCLK im Ruhezustand auf high, dann geht /CS auf 
low, dann folgt die Übertragung, SCLK geht wieder auf high und 
anschließen /CS auf high. Bei dir ist mindestens der Clock im Ruhzustand 
auf low.

von Uwe (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

eProfi schrieb:
> SUPPLY DECOUPLING
> The ADT7301 should be decoupled with a 0.1 μF ceramic capacitor between
> VDD and GND. This is particularly important if the ADT7301 mount is
> remote from the power supply.

Ist gemacht.

eProfi schrieb:
> An sich ein schickes Teil (1/32 ° Auflösung), was kosten die und wo gibt
> es die?

Die gibt es z.B. bei Schuricht ( www.distrelec.de ). Kosten 2,84 Euro.
Machen +-1Grad.

Matthias schrieb:
> In dem Datenblatt liegt SCLK im Ruhezustand auf high, dann geht /CS auf
> low, dann folgt die Übertragung, SCLK geht wieder auf high und
> anschließen /CS auf high. Bei dir ist mindestens der Clock im Ruhzustand
> auf low.

Das habe ich nun mit
1
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0)|(1<<CPOL);

geändert. Die Clock leigt nun im Ruhezustand uaf High. Während dem 
Empfang sende ich zwei mal 0x00. Somit liegt der Pin 2 des Sensors auf 
Low und er dürfte nicht in den Ruhezustand kommen.

eProfi schrieb:
> Mit den 2 Bits CPOL und CPHA gibt es ja 4 Möglichkeiten (die schon
> manchen Entwickler zum Verzweifeln brachten)

Das kenne ich ;)

Im Anhang mal ein neue Screenshot mit den Einsellungen von oben. Signale 
von unten nach oben: MOSI, CS, CLOCK, MISO

Vielen Dank!
Gruß
Uwe

von irgendeiner (Gast)


Lesenswert?

Liegt die Vcc genug lange vor dem Init an?
Mach mal ein Delay von 1,5 - 2 Sekunden vor und nach dem Init rein.
Du fragst ja auch nur einmal ab, versuche das öfters.

von Uwe (Gast)


Lesenswert?

Hallo,

ich habe die Abfrage einmal in eine Schleife gepackt, aber es wird immer 
das gleiche vom Sensor gesendet.

Das mit dem Delay vor und nach dem Init habe ich auch versucht, das 
brachte aber leider auch keine Änderung.

Vielen Dank!
Gruß
Uwe

von eProfi (Gast)


Lesenswert?

Da bin ich leider genauso ratlos wie Du.
Bitte messe mal direkt am Din-Pin, ob da wirklich L anliegt 
(Leitungsunterbrechung?).
Vielleicht liegt es an einer zu langsam ansteigenden Vcc (kein interner 
Reset)?

Wenn Du mir einen oder zwei schickst, versuche ich es mal.

Oder nimm was anderes. Wenn Du die hohe Auflösung brauchst: die alten 
Dallas mit den zwei Oszillatoren (z.B. DS1820, DS1620) haben eine sehr 
hohe (allerdings temperaturabhängige) Auflösung von < 0,01°C.
Beitrag "Re: DS18S20 hohe Auflösung berechnen"

Falls Du es schaffst: bitte hier posten, es interessiert mich / uns.

von Uwe (Gast)


Lesenswert?

Hallo,

ich habe den Din-Pin jetzt einfach mal direkt auf Masse gezogen. Somit 
liegt auf jeden Fall immer Low am Din-Pin an. Daran lag es aber nicht.

Ich habe hier mal meine Kramkisten durchsucht und noch einen 
Temperatursensor von TI gefunden. Hatte ich wohl mal als Sample 
bestellt. Per SPI ausgelesen funktionierte auf anhieb. Komisch , 
komisch.

Ich habe noch zwei weitere von den ADTs hier. Die werde ich mal testen. 
Ich glaube aber eher nicht, dass die alle hin sind. Bis jetzt habe ich 
ja zwei probiert aus der gleichen Bestellung, aber bei beiden genau das 
gleiche Bild, deswegen denke ich, dass es doch an irgendwelchen SPI 
EInstellungen liegt.

Vielen Dank!
Gruß
Uwe

von Uwe (Gast)


Lesenswert?

Hallo,

ich habe den Fehler wohl gefunden. Die Sensoren sind in Ordnung. Ich 
habe eine Platine mit dem Controller drauf undeine andere mit dem 
Sensor. Dazwischen ein Kabel. 25-30cm lang. Mit dem langen kabel kommt 
nur Mist raus.. Kürze ich das Kabel auf 5cm funktioniert alles 
wunderbar. Also liegt es wohl an den langen Kabeln. Da muss ich mir nun 
mal etwas einfallen lassen.

Gruß
Uwe

von eProfi (Gast)


Lesenswert?

Danke, dass Du Dich nochmal rührst.
Bei langen Leitungen treten Reflexionen auf, wenn sie hart getrieben 
werden. Diese kann man dämpfen, indem man ein- oder beidseitig Rs 
einfügt:

    ------ R ------------------------------------------- R ------

Richtwert: 10 bis 100 Ohm

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.