mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Temp.Sensor TSIC 306 - Temperaturwert


Autor: Axel (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe mir einen Temperatursensor TSIC 306 besorgt. Bevor ich mich an 
mein Programm heranmache (Assembler/ATMEGA8), habe ich ein 
Verständnisproblem.

Im beigefügten Datenblatt ist eine Tabelle:

Temp C    Hex didital
-10       0x199
  0       0x200
 25       0x2FF

Auflösung 0,1K; Digitaler Anschluss 11 bit

Also wenn 0 Grad einem Hexwert von 0x200 entsprechen, dann sind es doch 
bei einer Auflösung von 0,1 K 250 Schritte bis zu 25,0 Grad.
25,0 Grad entsprechen aber 0x2FF (255 Schritte).

Kann mir das bitte jemand erklären?

Vielen Dank

Autor: Martin Kirchner (mkkirchner)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
Mit Auflösung ist die ECHTE Auflösung des Sensors gemeint.
Also in welcher Auflösung er in der Lage ist zu Messen. Diese muss nicht 
exact der digitalen Auflösung entsprechen.
Meines Wissens misst der Tsic mit einer genauigkeit von +/- 0,3°C
Zum berechnen der Temperaturausgabe des TSIC gilt:
Temperature = (Digital signal/2047 * 200 - 50) °C

Siehe auch unter:
http://www.semiconductorstore.com/pdf/ZMD/TSic306.pdf
Für PICs kann ich auch ein Beispiel liefern (CCS Compiler).
float readTsic1()
{
int i=0;
int A=1;
int16 BIN=256;
int16 temp_value1 = 0;
int16 temp_value2 = 0;
int16 Temperature=0;
int8 parity;




delay_ms(10);

output_high(TSICPOWER);
delay_us(120);

//READ FIRST BYTE
  while (input(Pin_C0)); // wait until start bit start
  while (!input(Pin_C0));
  for (i = 0; i < 9; i++) 
 {
    while (input(Pin_C0));              // wait for falling edge
    delay_us(60);
    if (input(Pin_C0))    
         temp_value1 = temp_value1 + BIN ;
      else
        while (!input(Pin_C0)); // wait until line comes high again
  BIN=BIN/2;
  }
  

 BIN=256;

  while (input(Pin_C0));
  while (!input(Pin_C0));
  for (i = 0; i < 9; i++) 
 {
    while (input(Pin_C0));               // wait for falling edge
    delay_us(60);
    if (input(Pin_C0))
          temp_value2 = temp_value2 + BIN ;
      else
        while (!input(Pin_C0));            // wait until line comes high 
  BIN=BIN/2;
  }



  output_low(TSICPOWER);                           

BIN=1;

// check parity for byte 1
  parity = 0;
 for (i = 0; i < 9; i++)
   {
    if (temp_value1 & BIN){parity++;}
    BIN=BIN*2;
   }
  if (parity % 2){A=0;}


// check parity for byte 2
  parity = 0;
  BIN=1;
  for (i = 0; i < 9; i++)
    {
    if (temp_value2 & BIN){parity++;}
    BIN=BIN*2;
    }
 if (parity % 2){A=0;}

  temp_value1 >>= 1;                 // delete parity bit
  temp_value2 >>= 1;                 // delete parity bit
  Temperature = (temp_value1 << 8) | temp_value2;
  if (A!=0) return((float)Temperature/2047*200)-50;
  if (A==0) return(-99);

}
Martin

Autor: tt2t (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Die Schrittweite ist nicht die Auflösung.

Temp C    Hex digital
-50.0     0x000
-10       0x199
  0.0     0x200
 25       0x2FF
150.0     0x7FF

Diese Tabelle ist richtig, die Tabelle geht linear durch, anbei eine 
komplette Übersetzungstabelle.

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Martin, tt2t,

Vielen Dank für die Erklärung. Ich habe die möglichen HexWerte mal in 
Excel mit der Formel

(Digital signal/2047 * 200 - 50) °C

ausgewertet. Das entspricht dann den Temp-Werten der cvs-Datei von tt2t. 
:-)

Ich werde mir mal die Vorgehensweise in deinen C-Code anschauen und 
versuchen, es in Assembler umzusetzen.


Vielen Dank euch beiden
Axel

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Ich werde mir mal die Vorgehensweise in deinen C-Code anschauen und
>versuchen, es in Assembler umzusetzen.

Kleiner Tip:

>Digital signal/2047 * 200 - 50

Nimm statt 2047 2048. Das verfälscht das Ergebnis nur unwesentlich, 
erleichtert aber das Rechnen in Assembler wesentlich.

MfG Spess

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und dann Formel umstellen und kürzen.
 * 100 / 1024

Auch sollte man sich über Fixedpoint Arithmetik Gedanken machen, wenn 
man 1 Nachkommastelle haben will.

Autor: tt2t (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
für PICs habe ich eine Assembler-Routine zum Einlesen des 
Zacwire-Protokolls. Komme z.Zt. nur nicht ran, bin auf Arbeit.

Autor: Horst Hahn (horha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

TSIC wurde schon öfter behandelt:
dort http://www.mikrocontroller.net/articles/Temperatur... mit 
weiterführenden Verweisen.

Autor: tt2t (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: tt2t (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hier ist der ASM-Code drin
Beitrag "Re: digitaler Thermosensor"

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>hier ist der ASM-Code drin

Ja, für PIC. Also nicht so richtig passend ATMega8.

MfG Spess

Autor: pata (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> hier ist der ASM-Code drin
> Ja, für PIC. Also nicht so richtig passend ATMega8.

Aber die Abfragestrategie ist gut erklärt, die kann man für AVR ja 
nachbauen.

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

> Nimm statt 2047 2048. Das verfälscht das Ergebnis nur unwesentlich,
> erleichtert aber das Rechnen in Assembler wesentlich.

> Und dann Formel umstellen und kürzen.
> * 100 / 1024

> Auch sollte man sich über Fixedpoint Arithmetik Gedanken machen, wenn
> man 1 Nachkommastelle haben will.

da habe ich ja nochmal richtig viele, gute Tipps bekommen!



Ich bin mir sicher, dass ich mit den verschiedenen Beispielen mein 
Programm in Assembler umsetzen kann.


Vielen Dank an Alle
Axel

Autor: michaela1234 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das mit dem Multiplizieren und Teilen geht noch einfacher:

in *100/1024 ist noch ein Vielfaches von 4 drin, also:

*25/256 (das 256 wird noch interessant)

25x=3*8*x+1*x

der TSIC gibt 11bit mit fuehrenden Nullen aus, also nehmen wir ein 16bit 
Register
11bit *3 ergibt 13 bit (0x7FF*3=0x17FD=0b1011111111101)

in asm ergibt sich dann folgendes (nennen wir das Register R1:R2 in dem 
der erhaltene Wert vom TSIC steht, das Ergebnisregister R3:R4):

 ADD R4,R2 ; 3 mal addieren, entspricht mal 3 (3*x)
 ADC R3,R1

 ADD R4,R2
 ADC R3,R1

 ADD R4,R2
 ADC R3,R1

 LSL R3 ;dann 3 mal linksshift (ist mal 8)(3*8*x)
 ROL R4

 LSL R3
 ROL R4

 LSL R3
 ROL R4

 ADD R4,R2 ; noch einmal das Register R1:R2 dazu (+1x)
 ADC R3,R1


(das Register ist dann mit 16bit gefuellt, 13bit +3bit)

und nun die Division durch 256:

gar nix, denn das Ergebnis des vollen Temperaturwerts steht in R3, der 
Nachkommaanteil in R4.

wer will, kann nu den Nachkommaanteil noch runden:

die Formel fuers Runden auf 2 Nachkommastellen lautet:
x=INT(100x+0,5)/100 (aeh, das ist aber net in asm....)

fuer eine Stelle dann halt:
x=INT(10x+0,5)/10

gruss
wolf

Autor: michaela1234 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sry fuer Doppelpost...

hab aber grad gesehen, dass ich vergessen hab, 50 abzuziehen...
also:

Ergebnis des vollen Temperaturwerts steht in R3
davon 50 abziehen:

subi r3,50
(Achtung: SUBI geht nur mit Register R16..R31)

Autor: Jürgen W. (juergen_w) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ich gerade eine TSic206 am Start habe, hier meine Routine 
(Tiny2313,ASM)
;11Bit Rohwert des TSic in Temperatur umrechnen
;Originalformel aus dem Datenblatt T= (Digital_signal/2047*(HT-LT)+LT) [°C]
;LT = -50,  HT = 150 als Standardwert für die Temperatur-Berechnung
;
;Umgestellt für ASM
;t=TSic_Wert*200 /2048-50   (die 2047 um 1 erhöht um besser rechnen zu können)
;t=TSic_Wert*25/256-50  (gekürzt /8)
;Da eine Stelle hinter dem Komma angezeigt wird, rechne ich die Temperatur*10 und setze
;vor die letzte Stelle den Dezimalpunkt (Festkomma).
;Temperatur*10=(TSic_Wert*250)/256-500
mul250:
;zuerst rawlow/high mit 250 multiplizieren. 24Bit Ergebniss in Temp3/2/1(HSB, MSB, LSB)

  ldi    temp1,128    ;LSB runden
  mov    temp2,rawlow
  mov    temp3,rawhigh  
  lsl    rawlow      ;*2
  rol    rawhigh
  add    rawlow,temp2  ;*3
  adc    rawhigh,temp3
  lsl    rawlow      ;*6
  rol    rawhigh
  sub    temp1,rawlow  ;*256 - *6 = *250
  sbc    temp2,rawhigh  ;TSic_Wert*250 steht jetzt in temp1/temp2/temp3
  sbci  temp3,0      ;Durch verwerfen des LSB (temp1) wird durch 256 geteilt  
  subi  temp2,low(500)  ;500 (50.0) abziehen
  sbci  temp3,high(500)
  ret
;Nun steht die Temperatur(*10) in temp2 (low) und temp3 (high)
;--------------------------------------------------------------------------------------- 

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.