Temperaturmessung mit PT100 und MAX31865

In dieses Forum gehören all deine Fragen rund um die Elektrotechnik und im Speziellen zum Bereich der Mikrocontrollertechnik.

Re: Temperaturmessung mit PT100 und MAX31865

#21

Ungelesener Beitrag Nico » 15. Apr 2019, 18:18

Ich würde dir die Umsetzung schon mit dem Pointer Ansatz empfehlen:

Code: Alles auswählen

#define SCLK	LATFbits.LF3
#define SDO	LATDbits.LD2
#define SDI 	PORTDbits.RD1

void spi_transfer (uint8_t *pWr, uint8_t *pRd, uint8_t len)
{
   uint8_t i;
	
   // pull down the clock level
   SCLK = 0;
	
   // return if send data is not defined
   if(pWr == NULL) return;
	
   while(len)
   {
      for(i=0; i<8; i++)
      {
         // send bits from MSB to LSB
         SDO = (*pWr) & (0x80 >> i);
         // <-- delay at least 100ns
         // clock toggle
         SCLK ^= 1;
         
         // read from MSB to LSB (if read pointer is not NULL)
         if(pRd)
         {
            if(SDI)
            {
               *pRd |= (0x80 >> i);
            }
            else
            {
               *pRd &= ~(0x80 >> i);
            }
         }
         
         // <-- delay at least 100ns
         SCLK ^= 1;
      }

      pWr++;
      if(pRd) pRd++;
      len--;
   }
   
   // clock level idle high
   SCLK = 1;
}
Nutzen kannst du die Funktion dann so:

Code: Alles auswählen

uint8_t buf [8];

// ...

// write two bytes without read
buf [0] = 0x80;
buf [1] = ....;
cs = low;
spi_transfer(buf , NULL, 2);
cs = high;

// ...

// read two bytes starting from <RTD MSBs>
buf[0] = 0x01;
buf[1] = 0x00; // nicht zwingend notwendig aber sauberer zum Messen =)
buf[2] = 0x00; // nicht zwingend notwendig aber sauberer zum Messen =)
cs = low;
spi_transfer(buf , buf , 1+2);
cs = high;
Die 1+2 habe ich lediglich so geschrieben, damit der Zusammenhang etwas offensichtlicher wird. Du durchläufst zum Lesen von (hier als Beispiel zwei Bytes) in Summe drei Zyklen: 1. Das Senden der Adresse von der an beginnend du im Anschluss lesen möchtest (im Beispiel 0x01, wie im Datenblatt als Lese-Adresse für RTD MSBs angegeben). 2. und 3. sind die zwei Zyklen zum Lesen von RTD MSBs (hier beginnt das Lesen) und von RTD LSBs (da es direkt nach der Adresse für RTD MSBs liegt).

Vielleicht ist dir aufgefallen, dass beim Aufruf von spi_transfer() der Übergabeparameter für den Sende- und den Lesebuffer beides mal die Startadresse desselben Arrays genutzt wurde:

Code: Alles auswählen

spi_transfer(buf , buf , 1+2);
Der Funktion ist das egal, denn sie arbeitet sich Byte für Byte durch die einzelnen Bits durch und zwar beginnend beim MSB. Nehmen wir spaßeshalber mal an, dass in buf an der ersten Stelle des Arrays, also in buf[0], der Wert 0xAA steht (willkürlich gewählt) und wir auch lediglich einen einzigen Zyklus (len=1) durchlaufen.

Was würde passieren?

Die Funktion würde immer zum Senden der Bits auf die selbe Variable greifen, wie beim Einlesen der Bits und zwar in der Reihenfolge:
  • Senden Bit i
  • Einlesen Bit i
  • i um eins hochzählen
  • Solange wiederholen, bis i>7 (also 8 mal)
Nehmen wir außerdem an, dass ein IC, an das wir die 0xAA senden zeitgleich das Byte 0x55 sendet. Also während wir 0xAA auf SDO senden, empfangen wir 0x55 auf SDI. Der Ablauf wäre demnach wie folgt (vereinfacht ausgedrückt)

Senden (SDO): 0xAA = 0b10101010
Empfangen (SDI): 0x55 = 0x01010101
  • Senden Bit 7 [=1] auf SDO
  • Einlesen Bit 7 [=0] von SDI (dieses Bit wird nun in den Buffer geschrieben wo die 0xAA steht - das ist okay, da dessen Bit (7) ja gerade schon gesendet wurde und es somit nicht mehr gebraucht wird)
  • Fortfahren bis alle Bits gesendet/empfangen
Gruß Nico



Nachtrag: Nach dem Aufruf von spi_transfer(buf , buf , 1+2); stehen die zwei gelesenen Bytes in buf[1] (RTD MSBs) und buf[2] (RTD LSBs). Natürlich steht auch etwas in buf[0] aber da der MAX hier noch nichts gesendet hat (das war der Zyklus in dem wir dem MAX das Adressbyte gesendet haben), ist dieses Byte nicht von Interesse.

Re: Temperaturmessung mit PT100 und MAX31865

#22

Ungelesener Beitrag emy » 16. Apr 2019, 12:46

Danke für deine ausführliche Erklärung. Jetzt habe ich das mit dem Lesen auch verstanden :D

Ein Test für das Schreiben mit den Pointern funktioniert leider nicht so wie ich das möchte.

Code: Alles auswählen

buf [0] = 0x80;
Damit zeigt das Oszi nichts an, nur wenn dort 0x01 beispielsweise eingetragen ist, entstehen laufend Peaks. Bei Veränderung des Wertes, bleibt die Anzeige entweder genau gleich oder zeigt nichts an.

Mir ist noch nicht ganz klar, was die Zeilen

Code: Alles auswählen

SDO = (*pWr) & (0x80 >> i);
*pRd |= (0x80 >> i);
*pRd &= ~(0x80 >> i);
genau machen... Wenn du mir das noch kurz erklären könntest, damit ich evtl. meinen Fehler, warum die Adresse und das "Wort" nicht gesendet werden, finde …

Re: Temperaturmessung mit PT100 und MAX31865

#23

Ungelesener Beitrag Nico » 16. Apr 2019, 14:50

Versuch mal folgendes:

Diese Zeile:

Code: Alles auswählen

SDO = (*pWr) & (0x80 >> i);
Durch diese ersetzen:

Code: Alles auswählen

SDO = ((*pWr) & (0x80 >> i)) ? 1 : 0;
Zur Erklärung:

Code: Alles auswählen

SDO = (*pWr) & (0x80 >> i);
*pRd |= (0x80 >> i);
*pRd &= ~(0x80 >> i);
Zeile 1: Mit dem * sagst du, dass du nicht den Pointer selbst (also die Adresse) sondern den Wert haben möchtest, der an dieser Adresse steht. Also angenommen du hast vor dem Aufruf der SPI-Transfer Funktion einen Buffer mit uint8_t buf[8] angelegt und an die Funktion dann den Pointer buf übergeben, dann ist pWr ein Pointer auf den ersten Eintrag von buf also auf buf[0]. Der Einfachheit halber hier mal eine Veranschaulichung:

Code: Alles auswählen

Adresse    | Inhalt | Kommentar
-----------+--------+------------------
0x70000000 |  0xAA  | Hier liegt buf[0]
-----------+--------+------------------
    ...    |  ....  |
-----------+--------+------------------
0x80000000 |  0x00  | Das hier
-----------+--------+------------------
0x80000001 |  0x00  | ist der
-----------+--------+------------------
0x80000002 |  0x00  | Pointer
-----------+--------+------------------
0x80000003 |  0x70  | auf buf[0]
Also irgendwo im Speicher liegt dein Array buf mit seinen acht uint8_t Einträgen und an einer anderen Stelle liegt der Pointer, den du an die SPI Funktion übergeben hast. Bitte häng dich nicht an den Adressen auf, die sind bloß ausgedacht und machen unter Umständen keinen Sinn. Lediglich als Vereinfachung an dieser Stelle ;-)

Der Pointer muss entsprechend mehrere Speicherzellen belegen, da eine Adresse größer ist als bloß ein Byte - aber das ist hier jetzt gar nicht wichtig. Mir geht es darum, dass der Wert des Pointers (siehe Spalte Inhalt) ja erstmal gar nichts mit dem Wert der Variable zu tun hat, auf den er zeigt, also mit buf[0]. Damit wir nicht den Wert (das ist die Adresse) bekommen, sondern den Wert der Variable auf den der Pointe zeigt, nutzen wir den * Opertaor - siehe auch Tutorial.

Zurück zur Erklärung der Zeile:

Code: Alles auswählen

SDO = (*pWr) & (0x80 >> i);
Hier geschieht nichts weiter als, dass der Inhalt der Variable auf den der Pointer gerade zeigt mit bitweise und mit 0x80 >> i verglichen wird. Da i von 0 bis 7 in der for Schleife laufen wird, und somit die 0x80 immer weiter nach rechts verschiebt, wird also Bit für Bit auf eine 1 geprüft. Mit einfachen Worten: Im ersten Durchlauf der for und while Schleife: Ist Bit 7 von buf[0] eine 1? Wenn ja, setz SDO. Danach (2er Durchlauf der for aber immer noch erster Durchlauf der while Schleife: Ist Bit 6 von buf[0] eine 1? Wenn ja, setz SDO. Das wiederholt sich bis die while Schleife len mal durchlaufen wurde. Am Ende der while Schleife wird der Pointer stets um eins weiter gesetzt, so dass er (sofern über len vorgebeben) dann auf buf[1], buf[2] ... zeigt.

Die anderen beiden Zeilen (zum Einlesen):

Code: Alles auswählen

*pRd |= (0x80 >> i);
*pRd &= ~(0x80 >> i);
Da du jetzt bereits weißt, was es mit dem * auf sich hat, brauche ich darauf nicht mehr weiter eingehen. Hier wird also nun schreibend auf den Inhalt auf den der Pointer zeigt zugegriffen. Ich habe hier abgekürzte Schreibweisen verwendet, die man länglich auch so schreiben könnte:

Code: Alles auswählen

*pRd = (*pRd) | (0x80 >> i);
*pRd = (*pRd) & ~(0x80 >> i);
Im ersten Fall (also mit |) wird ein bitweises Oder ausgeführt. Da die Klammer vorrand hat, wird zunächst die 0x80 (also die 1 an Stelle von Bit 7) soweit nach rechts verschoben, wie i es angibt. Also wenn i=0 ist, dann bleibt der Klammerausdruck bei 0x80, wenn i=7 ist wird aus dem Klammerausdruck 0x01. Mit anderen Worten die erste Zeile setzt das i-te Bit (auf 1) in der Variable auf die pRd zeigt.

In der anderen Zeile passiert das Gegenteil: Der Klammerausdruck ist gleich bis auf das vorangestellte ~. Dieser Operator wird alle Bits umdrehen (aus 0 wird 1 und umgekehrt). Somit wird aus der Klammer wenn i=0 ist ein 0x7F bzw. ein 0xFE wenn i=7 ist. Mit anderen Worten: Hier wird das i-te Bit in der Variable auf die pRd zeigt gelöscht (auf 0 gesetzt).

Warum jetzt mein Gedanke die Zeile (siehe oben) auf diese zu ändern?

Code: Alles auswählen

SDO = ((*pWr) & (0x80 >> i)) ? 1 : 0;
Ohne den hinzugefügten Teil (? 1 : 0) würden verschiedene Werte ungleich 0 auf den GPIO geschrieben werden, wenn das jeweilige Bit eine 1 war. Ich bin mir aus dem Kopf gerade nicht ganz sicher ob das funktioniert. Du weißt, dass du mit folgender Zeile einen GPIO auf high setzen kannst:

Code: Alles auswählen

LATAbits.LA0 = 1;
Aber geht es auch so (und genau das war der Fall vor der Änderung)?

Code: Alles auswählen

LATAbits.LA0 = 2;
// oder
LATAbits.LA0 = 4;
// ...
Das ist jetzt bloß eine Idee. Wie gesagt ich hatte den Code nicht praktisch ausprobiert. Bitte versuch es mal mit der Änderung. Wenn es nicht klappt, simuliere ich es zu Hause mal durch.

Gruß Nico

Re: Temperaturmessung mit PT100 und MAX31865

#24

Ungelesener Beitrag emy » 17. Apr 2019, 16:43

Es funktioniert :) :) :) :) !!! Das was ich will, wird gesendet!

Die Funktion für das Lesen benötigt ja einen Returnwert, ist es in diesem Fall dann das 16 Bit lange Wort aus MSB und LSB, sprich buf[1] und buf[2]?
Dafür muss ja sicherlich der MSB Inhalt um 8 Stellen nach links geshiftet werden und dann mit einem ODER der LSB Inhalt drangehängt werden?
Ich dachte dann dabei an so etwas:

Code: Alles auswählen

return ((buf[1] << 8) | buf[2]);
buf[0] hat uns hier ja nicht zu interessieren. Wenn ich das dann mit

Code: Alles auswählen

adccode = maxRTD_read();
einer Variablen übergebe und die Temperatur mit

Code: Alles auswählen

double temp;
temp = (adccode / 32) - 256;
berechne, müsste dann doch die Temperatur (hier zur Zeit Zimmertemperatur) in der Variablen temp stehen oder?
Ach miste, in meiner Überlegung fehlt das Shiften um einen nach rechts des ADC-Codes.

Code: Alles auswählen

double temp;
temp = ((adccode >> 1) / 32) - 256;
lieber so vielleicht …

Re: Temperaturmessung mit PT100 und MAX31865

#25

Ungelesener Beitrag Nico » 17. Apr 2019, 18:00

Cool, dass die SPI Kommunikation jetzt schon mal klappt.

Ich würde an deiner Stelle nicht vollständig auf das Fault Bit des Sensors verzichten. Ansonsten würdest du ja nie mitbekommen ob eine Messung tatsächlich gültig oder fehlgeschlagen ist und somit verworfen werden sollte. Hier eine Möglichkeit dies mit aufzufangen:

Code: Alles auswählen

uint8_t maxRTD_read (uint16_t *pRTD)
{
	uint8_t fault;
	uint8_t buf[3];

	/*
	 * - ggf. anfordern der neuen Messung und warten auf DRDY
	 * - auslesen der Register MSB/LSB
	 */
	 
	 // ...
	 
	 // prüfen des FAULT bit
	 fault = buf[2] & 0x01;
	 
	 if(!fault) {
	 	*pRTD = (buf[1] << 7) | (buf[2] >> 1);
	 }

	return fault;
}
Der RTD Wert würde direkt in die Variable geschrieben auf die pRTD zeigt und ist nur dann gültig, wenn maxRTD_read() eine 0 zurück gibt.

Bezüglich der Berechnung des Temperaturwertes: Hier kannst du noch etwas optimieren ;-) Je nachdem wie dein Compiler konfiguriert ist, würde er das zwar auch selbstständig erledigen, wir wollen ja aber auch was lernen. Also aus dieser Zeile:

Code: Alles auswählen

temp = ((adccode >> 1) / 32) - 256;
Kannst du einfach diese machen:

Code: Alles auswählen

temp = (adccode >> 6) - 256;
Wie gesagt, werden diese Werte relativ ungenau sein (aufgrund der Approximation mit einer Geraden). An dieser Stelle eine Frage: Weshalb willst du im PIC überhaupt irgendeine Berechnung der Temperatur durchführen? An deiner Stelle würde ich den AD-Wert 1:1 nehmen und senden. Die Auswertung kann doch dann ganz bequem beim Empfänger durchgeführt werden (dann z.B. mit der Callendar Van Dusen Gleichung oder eben via Tabelle).

PS: Hast du an die notwendigen Wartezeiten in der spi_transfer() Funktion gedacht, damit der SPI Takt nicht zu schnell für den MAX wird?

Gruß Nico

Re: Temperaturmessung mit PT100 und MAX31865

#26

Ungelesener Beitrag Nico » 18. Apr 2019, 07:09

Wobei mir jetzt noch eingefallen bzw. aufgefallen ist, wenn du die Temperaturberechnung wirklich auf dem PIC machen möchtest, ist mein Vorschlag keine gute Idee:

Code: Alles auswählen

temp = (adccode >> 6) - 256;
temp ist ja vom Typ ein double und da sind die Bit-Shift Operanden Unsinn. Es müsste dann eher so aussehen (der Cast auf double ist ggf. nicht notwendig, wenn du wirklich 32.0 statt 32 schreibst):

Code: Alles auswählen

temp = (double)(adccode / 32.0) - 256;
Sorry, arbeite i.d.R. eher selten mit Floating-Point Typen.

Gruß Nico

Re: Temperaturmessung mit PT100 und MAX31865

#27

Ungelesener Beitrag emy » 18. Apr 2019, 10:53

Der MAX31865 antwortet! :)

Mit Hilfe eines brakpoints lasse ich mir die Variable "temp" anzeigen. Derzeit noch ohne das Auffangen des Faultbits, was du davor vorgeschlagen hast (finde ich aber gut und möchte ich auch umsetzen :) ). Es werden mir in "temp" 4 Bytes ausgegeben: 11000011, 10000000, 00000000, 00000000.

Aktuell verwende ich diesen Code:

Code: Alles auswählen

void spi_transfer (uint8_t *pWr, uint8_t *pRd, uint8_t len){
           uint8_t i; 
           
           clock = 0;
           
           if (pWr == NULL) return;
           
           while (len){
               for (i=0; i<8; i++){
                    SDO = ((*pWr) & (0x80 >> i)) ? 1 : 0;
                   __delay32(100);
                   clock ^= 1;
                   
                   if (pRd) {
                       if (SDI){
                           *pRd |= (0x80 >> i);
                       }
                       else {
                           *pRd &= ~(0x80 >> i);
                       }
                      
                   }
                __delay32(100);
                clock ^=1;    
               }
               pWr++;
               if (pRd) pRd++;
               
               len--;
           }
           clock = 1;
        
        }
        

Code: Alles auswählen

void maxRTD_request_new_meas (void)
    {
        uint8_t buf[8];
        
        buf[0] = 0x80;
        buf[1] = 0xC2;
        
        cs_max = 0;
        spi_transfer(buf, NULL, 2);
        cs_max = 1;
    }

    uint16_t maxRTD_read_res (void)
    {
        uint8_t buf[8];
        
        buf[0] = 0x01;
        buf[1] = 0x00;
        buf[2] = 0x00;
        
        cs_max = 0;
        spi_transfer(buf, buf, 3);
        cs_max = 1;
        
        return ((buf[1] << 8) | buf[2]);
    }

Code: Alles auswählen

int main(void)
{
    // initialize the device
    SYSTEM_Initialize();
    
    uint16_t adccode;
    double temp;
     
    while (1)
    {
        maxRTD_request_new_meas();
        adccode = maxRTD_read_res();
        temp =(double)(adccode / 32.0) - 256;

        int i = i+1;
    }

    return 1;
}
(i für den brakpoint)

Warum werden hier jetzt 4 Bytes ausgegeben? Oder sind die letzten beiden, die aus nur Nullen bestehen, "unwichtig"?

Re: Temperaturmessung mit PT100 und MAX31865

#28

Ungelesener Beitrag Nico » 18. Apr 2019, 11:52

Ein paar allgemeine Anmerkungen:
  • Du verwendet in deinem Code clock vermutlich als Ersatz für den GPIO, der den SPI Clock erzeugen soll? Es ist allgemein üblich Defines ausschließlich in Großbuchstaben zu schreiben. Also würde ich dir empfehlen clock durch CLOCK oder besser noch durch (etwas aussagekräftiger) SCLK (normale Bezeichnung für den SPI Clock) zu ersetzen.
  • Sofern du weißt bzw. es in deinem Code sauber dokumentiert ist, was __delay32 macht, dann okay. Grundsätzlich immer drauf achten, dass Namen, egal ob für Funktionen, Variablen oder sonstiges, aussagekräftig sind ;-)
  • Arbeite mit Kommentaren im Code. Das heißt nicht, dass man folgende Zeile a++; mit einem Kommentar // a inkrementieren versieht sondern vielmehr den Sinn/Zweck verdeutlicht. Du wirst sehen dass solche Kommentare Gold wert sind, wenn du mal etwas Zeit ins Land gehen lässt und zurück zu deinem Code kommst :-) Wie gesagt ein gesundes Maß an Kommentaren, nicht jede (offensichtliche) Zeile muss erklärt werden.
  • Besonders auf Mikrocontrollern, wo der Speicher nicht in Hülle und Fülle vorhanden ist, sollte man als Programmierer darauf achten nicht zu verschwenderisch zu sein. Also wenn ein Buffer lediglich zwei Werte fassen wird, mach ihn auch nur so groß.
Jetzt zu deiner Frage:
Warum werden hier jetzt 4 Bytes ausgegeben?
Das liegt an dem Datentyp double. Bitte schau mal in MPLABX nach: Öffne mal deine Project Properties (siehe links das Fenster Project - hier einen Rechtsklick auf den Projektnamen, dann Project-Properties) und geh dann auf Conf > XC8 global options > XC8 linker. Wähle dann rechts im Fenster "Memory Model" im Auswahlfeld aus und schau nach was bei Size of Double steht (24 oder 32 bit), siehe:

mplabx_memory_model_double.png

Es macht aber auch im Allgemeinen wenig Sinn sich eine Floating-Point Variable (also float oder double) im Binärformat anzusehen. Es sei denn man möchte wirklich das Format dieser lernen/verstehen. Im MPLAB kannst du dir den Wert von der Variable auch als Dezimalzahl anzeigen lassen, so dass du dann auch direkt die gemessene Temperatur sehen können solltest.

In deinem Code fehlt nun allerdings das Rechtsverschieben um eine Stelle (das Fault Bit gehört nicht zum eigentlichen ADC Wert). So wird die errechnete Temperatur nicht passen. Also entweder so realisieren, wie von mir zuvor vorgeschlagen oder das Fault Bit unter den Tisch fallen lassen, siehe deine Zeile (muss angepasst werden):

Code: Alles auswählen

return ((buf[1] << 8) | buf[2]);
Noch etwas: Das hier (in deiner while Schleife) macht keinen Sinn:

Code: Alles auswählen

int i = i+1;
Verschiebe das Erzeugen von i an den Beginn der main Funktion (mit Initialisierung auf 0) und schreib das Inkrementieren (i++;) dann in die Schleife.

Gruß Nico

Re: Temperaturmessung mit PT100 und MAX31865

#29

Ungelesener Beitrag emy » 18. Apr 2019, 12:39

Also würde ich dir empfehlen clock durch CLOCK oder besser noch durch (etwas aussagekräftiger) SCLK (normale Bezeichnung für den SPI Clock) zu ersetzen

Gemacht:)
Sofern du weißt bzw. es in deinem Code sauber dokumentiert ist, was __delay32 macht, dann okay
Die Funktion __delay_ms(100); und alle anderen möglichen Variationen funktioneiren nicht. Ich habe die __delay32 Funktion im Compiler-Handbuch gefunden...
Arbeite mit Kommentaren im Code
Die folgen auf jeden Fall noch, gerade sehr wichtig, wenn es in einer Thesis beschrieben wird.

Code: Alles auswählen

return ((buf[1] << 7) | (buf[2] >> 1));
Das ist jetzt der Returnwert, hatte ich vergessen das stimmt. Ich verwende den XC16 und dort ist die Einstellung für Size of Double nicht möglich. Habe jetzt auch ein bisschen herumprobiert, aber es kommen keine sinnigen Werte für die Temperatur zu stande. Als Dezimalzahl anzeigen lassen, hatte ich bereits, da das aber keinen Sinn ergab, wollte ich mir das ganze mal in binär angucken.

Hab jetzt spaßeshalber temp als Integer definiert (sind ja nur 16 Bit). Dann steht in temp immer die letzte Zahl der Zeile

Code: Alles auswählen

temp =(adccode / 32) - 256;
In diesem Fall jetzt 256, wenn ich die Zahl ändere, ändert sich auch temp zu dieser Zahl. Da stimmt dann ja irgendetwas nicht...

Re: Temperaturmessung mit PT100 und MAX31865

#30

Ungelesener Beitrag Nico » 18. Apr 2019, 13:24

Stimmt, du arbeitest ja gar nicht mit dem XC8, mein Fehler.

Also temp musst du auf jedenfall als double lassen. Hast du dir nach dem Auslesen des MAX mal die 15 Bit angesehen? Ist da evtl. das Fault Bit gesetzt?

Und kannst du vielleicht mal einen Screenshot von der Kommunikation zum MAX zeigen? Idealerweise die Config sowie das Auslesen.

Gruß Nico

Re: Temperaturmessung mit PT100 und MAX31865

#31

Ungelesener Beitrag emy » 18. Apr 2019, 14:24

Hast du dir nach dem Auslesen des MAX mal die 15 Bit angesehen?
Ja, 2 Bytes voller Nullen …
Und kannst du vielleicht mal einen Screenshot von der Kommunikation zum MAX zeigen? Idealerweise die Config sowie das Auslesen.
Von was genau soll ich einen Screenshot machen? Das "output" des progamms ist recht unspektakulär, oder was meinst du genau?

Viele Grüße

Re: Temperaturmessung mit PT100 und MAX31865

#32

Ungelesener Beitrag Nico » 18. Apr 2019, 14:29

Dann würde ich behaupten, dass bei der Übertragung noch irgendwas nicht stimmt, denn das wirklich alles Null ist, glaube ich nicht.
Von was genau soll ich einen Screenshot machen?
Von den gemessenen Signalen (SPI Kommunikation) zwischen dem PIC und dem MAX, also Chip Select, Clock und 2x Daten.

Re: Temperaturmessung mit PT100 und MAX31865

#33

Ungelesener Beitrag emy » 18. Apr 2019, 15:01

Es ist leider kein Screenshot, sondern ein Foto, weil das Ding alt ist....
von oben nach unten: Clock, SDO, CS, SDI.
IMG_20190418_145615.jpg

Re: Temperaturmessung mit PT100 und MAX31865

#34

Ungelesener Beitrag Nico » 18. Apr 2019, 15:21

Mh .. damit kann ich nicht so viel anfangen, da CS hier ja immer low zu sein scheint. Bitte setzt mal einen Breakpoint vor dem Konfigurieren des MAX und dann wieder vor dem Anfordern des Ergebnisses. So dass man auch vernünftig die zwei Zugriffe sieht.

Die Frequenz von SCLK liegt bei ~7..8kHz sofern ich mich nicht verlesen habe?

Re: Temperaturmessung mit PT100 und MAX31865

#35

Ungelesener Beitrag emy » 18. Apr 2019, 15:43

Ja die Frequenz von SCLK liegt bei 7,8 kHz.

Auf Kanal 1 wird gesendet, sobald das Senden beginnt, geht CS auf LOW. Es wird 1000 0000 1100 0010 gesendet, danach gibt es einen kurzen PEAK bei CS und dann wird die Adresse für das Lesen und zweimal 0x00 gesendet über SDO 0000 0001 0000 0000 0000 0000. Daraufhin hat CS wieder eine positive Flanke, das ist doch richtig so oder nicht? Im Kanal 7 hat SDI jedoch fast nur einen Pegel von 1. Einen Breakpoint kann ich mit dem Ding nicht darstellen, dafür bin ich nicht schnell genug :D

Antworten