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
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:
1 | 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).
1 | float readTsic1() |
2 | { |
3 | int i=0; |
4 | int A=1; |
5 | int16 BIN=256; |
6 | int16 temp_value1 = 0; |
7 | int16 temp_value2 = 0; |
8 | int16 Temperature=0; |
9 | int8 parity; |
10 | |
11 | |
12 | |
13 | |
14 | delay_ms(10); |
15 | |
16 | output_high(TSICPOWER); |
17 | delay_us(120); |
18 | |
19 | //READ FIRST BYTE |
20 | while (input(Pin_C0)); // wait until start bit start |
21 | while (!input(Pin_C0)); |
22 | for (i = 0; i < 9; i++) |
23 | { |
24 | while (input(Pin_C0)); // wait for falling edge |
25 | delay_us(60); |
26 | if (input(Pin_C0)) |
27 | temp_value1 = temp_value1 + BIN ; |
28 | else |
29 | while (!input(Pin_C0)); // wait until line comes high again |
30 | BIN=BIN/2; |
31 | } |
32 | |
33 | |
34 | BIN=256; |
35 | |
36 | while (input(Pin_C0)); |
37 | while (!input(Pin_C0)); |
38 | for (i = 0; i < 9; i++) |
39 | { |
40 | while (input(Pin_C0)); // wait for falling edge |
41 | delay_us(60); |
42 | if (input(Pin_C0)) |
43 | temp_value2 = temp_value2 + BIN ; |
44 | else |
45 | while (!input(Pin_C0)); // wait until line comes high |
46 | BIN=BIN/2; |
47 | } |
48 | |
49 | |
50 | |
51 | output_low(TSICPOWER); |
52 | |
53 | BIN=1; |
54 | |
55 | // check parity for byte 1 |
56 | parity = 0; |
57 | for (i = 0; i < 9; i++) |
58 | { |
59 | if (temp_value1 & BIN){parity++;} |
60 | BIN=BIN*2; |
61 | } |
62 | if (parity % 2){A=0;} |
63 | |
64 | |
65 | // check parity for byte 2 |
66 | parity = 0; |
67 | BIN=1; |
68 | for (i = 0; i < 9; i++) |
69 | { |
70 | if (temp_value2 & BIN){parity++;} |
71 | BIN=BIN*2; |
72 | } |
73 | if (parity % 2){A=0;} |
74 | |
75 | temp_value1 >>= 1; // delete parity bit |
76 | temp_value2 >>= 1; // delete parity bit |
77 | Temperature = (temp_value1 << 8) | temp_value2; |
78 | if (A!=0) return((float)Temperature/2047*200)-50; |
79 | if (A==0) return(-99); |
80 | |
81 | } |
Martin
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.
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
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
Und dann Formel umstellen und kürzen. * 100 / 1024 Auch sollte man sich über Fixedpoint Arithmetik Gedanken machen, wenn man 1 Nachkommastelle haben will.
für PICs habe ich eine Assembler-Routine zum Einlesen des Zacwire-Protokolls. Komme z.Zt. nur nicht ran, bin auf Arbeit.
Hallo, TSIC wurde schon öfter behandelt: dort http://www.mikrocontroller.net/articles/Temperatursensor#TSic mit weiterführenden Verweisen.
>> 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.
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
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
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)
Da ich gerade eine TSic206 am Start habe, hier meine Routine (Tiny2313,ASM)
1 | ;11Bit Rohwert des TSic in Temperatur umrechnen |
2 | ;Originalformel aus dem Datenblatt T= (Digital_signal/2047*(HT-LT)+LT) [°C] |
3 | ;LT = -50, HT = 150 als Standardwert für die Temperatur-Berechnung |
4 | ; |
5 | ;Umgestellt für ASM |
6 | ;t=TSic_Wert*200 /2048-50 (die 2047 um 1 erhöht um besser rechnen zu können) |
7 | ;t=TSic_Wert*25/256-50 (gekürzt /8) |
8 | ;Da eine Stelle hinter dem Komma angezeigt wird, rechne ich die Temperatur*10 und setze |
9 | ;vor die letzte Stelle den Dezimalpunkt (Festkomma). |
10 | ;Temperatur*10=(TSic_Wert*250)/256-500 |
11 | mul250: |
12 | ;zuerst rawlow/high mit 250 multiplizieren. 24Bit Ergebniss in Temp3/2/1(HSB, MSB, LSB) |
13 | |
14 | ldi temp1,128 ;LSB runden |
15 | mov temp2,rawlow |
16 | mov temp3,rawhigh |
17 | lsl rawlow ;*2 |
18 | rol rawhigh |
19 | add rawlow,temp2 ;*3 |
20 | adc rawhigh,temp3 |
21 | lsl rawlow ;*6 |
22 | rol rawhigh |
23 | sub temp1,rawlow ;*256 - *6 = *250 |
24 | sbc temp2,rawhigh ;TSic_Wert*250 steht jetzt in temp1/temp2/temp3 |
25 | sbci temp3,0 ;Durch verwerfen des LSB (temp1) wird durch 256 geteilt |
26 | subi temp2,low(500) ;500 (50.0) abziehen |
27 | sbci temp3,high(500) |
28 | ret |
29 | ;Nun steht die Temperatur(*10) in temp2 (low) und temp3 (high) |
30 | ;--------------------------------------------------------------------------------------- |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.