AVR - SHT11 liefert zu große Werte

Gast #1191727
Lesenswert?

Hallo,

ich versuche mit einem ATMega die Temperatur eines SHT11 auszulesen.
Leider ist in meinem Programm jedoch ein Logikfehler.
Es kommen immer zu große Werte beim auslesen raus.
(auch ohne die Rechnung, sondern in dem 16Bit Wert selber)
Es ändern sich jeweils nur die ersten 8 Bit des 16 Bit Integer.
Der SHT selber ist an PB0 und PB1 angeschlossen, ein Pullup an der DATA- 
Leitung (4k7) und ein 100n ist vorhanden.
Könnte dort mal bitte jemand drüber schauen ob er einen Fehler findet?!?


Gruß
Gast


1
#include <avr/io.h>
2
#include <util/delay.h>                
3

4
//Anschlussdefinition des SHT11
5
#define SHT_SCK_DDR      DDRB
6
#define SHT_DATA_DDR     DDRB
7

8
#define SHT_SCK_PORT     PORTB
9
#define SHT_DATA_PORT    PORTB
10

11
#define SHT_DATA_PIN_IN  PINB
12

13
#define SHT_SCK_PIN      PB0
14
#define SHT_DATA_PIN     PB1
15

16
//Einpegelzeit zwischen einem Flankenwechsel in ms
17
#define EINPEGELN       1
18

19

20
uint16_t TEMP = 0;              //Temp. Variable
21

22
//Prototypen
23
int Start_Temp_Messung (void);
24
int TransmissionStart(void);
25
int Adresse(void);
26
int Temperaturmessung(void);
27
int Tempaufnahme(void);
28
int Taktimpuls(void);
29
int Temp_umrechnung(void);
30

31
////////////////////////////////////////////////////////////////////////////////////////
32
int main(void)
33
{
34
  Start_Temp_Messung();
35

36
  //Testschleife für Breakpoint
37
  while(1) 
38
  {
39
  _delay_ms(1000);
40
  }
41
}
42
////////////////////////////////////////////////////////////////////////////////////////
43

44
////////////////////////////////////////////////////////////////////////////////////////
45
int Start_Temp_Messung(void)
46
{
47
_delay_ms(20);                          //Warte 20ms bis SHT in Sleep-Mode
48
TransmissionStart();                    //TransmissionStart- Sequenz
49
Adresse();                              //Adress- Sequenz (000)
50
Temperaturmessung();                    //Befehl -> Temperaturmessung (00011)
51
Tempaufnahme();                         //Empfangen des 14Bit Temp. Messwertes
52
Temp_umrechnung();                      //Umrechnung 16Bit Wert zu Temp.
53

54
return(0);
55
}
56
////////////////////////////////////////////////////////////////////////////////////////
57

58
////////////////////////////////////////////////////////////////////////////////////////
59
int TransmissionStart(void)
60
{
61
////////////Connection Reset Sequenz/////////////////
62
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen
63
SHT_SCK_DDR = SHT_SCK_DDR | (1<<SHT_SCK_PIN);           //Taktpin als Ausgang setzen
64
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen
65
Taktimpuls();                                           //Taktsignal -> H -> L
66
Taktimpuls();                                           //Taktsignal -> H -> L
67
Taktimpuls();                                           //Taktsignal -> H -> L
68
Taktimpuls();                                           //Taktsignal -> H -> L
69
Taktimpuls();                                           //Taktsignal -> H -> L
70
Taktimpuls();                                           //Taktsignal -> H -> L
71
Taktimpuls();                                           //Taktsignal -> H -> L
72
Taktimpuls();                                           //Taktsignal -> H -> L
73
Taktimpuls();                                           //Taktsignal -> H -> L
74
Taktimpuls();                                           //Taktsignal -> H -> L
75
Taktimpuls();                                           //Taktsignal -> H -> L
76
////////////Connection Reset Sequenz/////////////////
77

78
//SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen
79
//SHT_SCK_DDR = SHT_SCK_DDR | (1<<SHT_SCK_PIN);           //Taktpin als Ausgang setzen
80

81
//Transmission Start Sequenz
82
_delay_ms(EINPEGELN);     
83

84
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen
85
SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen
86

87
_delay_ms(EINPEGELN); 
88

89
SHT_SCK_PORT = SHT_SCK_PORT | (1<<SHT_SCK_PIN);         //Taktpin auf HIGH setzen
90

91
_delay_ms(EINPEGELN);     
92

93
SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen
94

95
_delay_ms(EINPEGELN);     
96

97
SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen
98

99
_delay_ms(EINPEGELN);     
100
                                         
101
SHT_SCK_PORT = SHT_SCK_PORT | (1<<SHT_SCK_PIN);         //Taktpin auf HIGH setzen
102

103
_delay_ms(EINPEGELN);     
104

105
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen
106

107
_delay_ms(EINPEGELN); 
108

109
SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen
110

111
_delay_ms(EINPEGELN); 
112

113
return(0);    
114
}
115
////////////////////////////////////////////////////////////////////////////////////////
116

117
////////////////////////////////////////////////////////////////////////////////////////
118
int Adresse(void)
119
{
120
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen
121
SHT_SCK_DDR = SHT_SCK_DDR | (1<<SHT_SCK_PIN);           //Taktpin als Ausgang setzen
122

123
//Übermitteln der Adresse (000)
124
_delay_ms(EINPEGELN);   
125

126
SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen
127

128
Taktimpuls();                                           //Taktsignal -> H -> L
129

130
Taktimpuls();                                           //Taktsignal -> H -> L
131

132
Taktimpuls();                                           //Taktsignal -> H -> L
133
return(0);
134
}
135
////////////////////////////////////////////////////////////////////////////////////////
136

137
////////////////////////////////////////////////////////////////////////////////////////
138
int Temperaturmessung(void)
139
{
140
//Übermitteln des Komandos
141
Taktimpuls();                                           //Taktsignal -> H -> L
142

143
Taktimpuls();                                           //Taktsignal -> H -> L
144

145
Taktimpuls();                                           //Taktsignal -> H -> L
146

147
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen
148

149
Taktimpuls();                                           //Taktsignal -> H -> L 
150

151
Taktimpuls();                                           //Taktsignal -> H -> L
152

153
_delay_ms(EINPEGELN);
154
SHT_DATA_DDR = SHT_DATA_DDR & ~(1<<SHT_DATA_PIN);       //Datenpin als Eingang setzen
155
SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen (PullUP OFF)
156

157
Taktimpuls();                                           //Taktsignal -> H -> L (ACK)
158

159
_delay_ms(450);                                         //Warte auf Messergebniss
160
//Warteschleife + Watchdog
161

162
return(0);
163
}
164
////////////////////////////////////////////////////////////////////////////////////////
165

166
////////////////////////////////////////////////////////////////////////////////////////
167
int Tempaufnahme(void)
168
{
169
TEMP = 0;
170

171
//Auslesen MSB
172
Taktimpuls();                                           //Taktsignal -> H -> L
173

174
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
175
{
176
TEMP = TEMP | (1<<15);                                  //Schreibe 1 in Bit 16 von MSB
177
}
178

179
Taktimpuls();                                           //Taktsignal -> H -> L
180

181
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
182
{
183
TEMP = TEMP | (1<<14);                                  //Schreibe 1 in Bit 15 von MSB
184
}
185

186
Taktimpuls();                                           //Taktsignal -> H -> L
187

188
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
189
{
190
TEMP = TEMP | (1<<13);                                  //Schreibe 1 in Bit 14 von MSB
191
}
192

193
Taktimpuls();                                           //Taktsignal -> H -> L
194

195
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
196
{
197
TEMP = TEMP | (1<<12);                                  //Schreibe 1 in Bit 13 von MSB
198
}
199

200
Taktimpuls();                                           //Taktsignal -> H -> L
201

202
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
203
{
204
TEMP = TEMP | (1<<11);                                  //Schreibe 1 in Bit 12 von MSB
205
}
206

207
Taktimpuls();                                           //Taktsignal -> H -> L
208

209
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
210
{
211
TEMP = TEMP | (1<<10);                                  //Schreibe 1 in Bit 11 von MSB
212
}
213

214
Taktimpuls();                                           //Taktsignal -> H -> L
215

216
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
217
{
218
TEMP = TEMP | (1<<9);                                   //Schreibe 1 in Bit 10 von MSB
219
}
220

221
Taktimpuls();                                           //Taktsignal -> H -> L
222

223
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
224
{
225
TEMP = TEMP | (1<<8);                                   //Schreibe 1 in Bit 9 von MSB
226
}
227

228
_delay_ms(EINPEGELN); 
229

230
//ACK zwischen den beiden 8- Bit- Feldern
231
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen (ACK)
232

233
_delay_ms(EINPEGELN);   
234

235
SHT_DATA_PORT = SHT_DATA_PORT & ~(1<<SHT_DATA_PIN);     //Datenpin auf LOW setzen
236

237
_delay_ms(EINPEGELN);  
238

239
Taktimpuls();                                           //Taktsignal -> H -> L
240

241
SHT_DATA_DDR = SHT_DATA_DDR & ~(1<<SHT_DATA_PIN);       //Datenpin als Eingang setzen
242

243
_delay_ms(EINPEGELN);
244

245
//Auslesen LSB
246
Taktimpuls();                                           //Taktsignal -> H -> L
247

248
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
249
{
250
TEMP = TEMP | (1<<7);                                   //Schreibe 1 in Bit 8 von MSB
251
}
252

253
Taktimpuls();                                           //Taktsignal -> H -> L
254

255
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
256
{
257
TEMP = TEMP | (1<<6);                                   //Schreibe 1 in Bit 7 von MSB
258
}
259

260
Taktimpuls();                                           //Taktsignal -> H -> L
261

262
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
263
{
264
TEMP = TEMP | (1<<5);                                   //Schreibe 1 in Bit 6 von MSB
265
}
266

267
Taktimpuls();                                           //Taktsignal -> H -> L
268

269
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
270
{
271
TEMP = TEMP | (1<<4);                                   //Schreibe 1 in Bit 5 von MSB
272
}
273

274
Taktimpuls();                                           //Taktsignal -> H -> L
275

276
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
277
{
278
TEMP = TEMP | (1<<3);                                   //Schreibe 1 in Bit 4 von MSB
279
}
280

281
Taktimpuls();                                           //Taktsignal -> H -> L
282

283
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
284
{
285
TEMP = TEMP | (1<<2);                                   //Schreibe 1 in Bit 3 von MSB
286
}
287

288
Taktimpuls();                                           //Taktsignal -> H -> L
289

290
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
291
{
292
TEMP = TEMP | (1<<1);                                   //Schreibe 1 in Bit 2 von MSB
293
}
294

295
Taktimpuls();                                           //Taktsignal -> H -> L
296

297
if (SHT_DATA_PIN_IN & (1<<SHT_DATA_PIN))                //Wenn Datenpin = 1 dann:
298
{
299
TEMP = TEMP | (1<<0);                                   //Schreibe 1 in Bit 1 von MSB
300
}
301

302
_delay_ms(EINPEGELN);
303

304
SHT_DATA_DDR = SHT_DATA_DDR | (1<<SHT_DATA_PIN);        //Datenpin als Ausgang setzen (ACK)
305

306
_delay_ms(EINPEGELN);  
307

308
SHT_DATA_PORT = SHT_DATA_PORT | (1<<SHT_DATA_PIN);      //Datenpin auf HIGH setzen (NO CRC)
309

310
Taktimpuls();                                           //Taktsignal -> H -> L
311

312
return(0);
313
}
314
////////////////////////////////////////////////////////////////////////////////////////
315

316
int Taktimpuls(void)
317
{
318
_delay_ms(EINPEGELN);
319

320
SHT_SCK_PORT = SHT_SCK_PORT | (1<<SHT_SCK_PIN);         //Taktpin auf HIGH setzen 
321

322
_delay_ms(EINPEGELN); 
323

324
SHT_SCK_PORT = SHT_SCK_PORT & ~(1<<SHT_SCK_PIN);        //Taktpin auf Low setzen 
325

326
_delay_ms(EINPEGELN);
327

328
return(0);
329
}
330

331
int Temp_umrechnung(void)
332
{
333
TEMP = TEMP * 0.01;
334
TEMP = TEMP - 40;
335
return(0);
336
}
Gast #1191760
Lesenswert?

Ich habe dass ganze in Bascom, dort hole ich die Temp. als 2x8Bit ab, 
jeder Block muss quittiert werden.
C kann ich nicht so toll, aber es sieht für mich aus als würdest du die 
Daten auf einmal holen wollen.
[quote]
Two bytes of measurement data and one byte of CRC
checksum (optional) will then be transmitted. The micro
controller must acknowledge each byte by pulling the
DATA line low. All values are MSB first, right justified
[/quote]

Gruß Anselm
Gast #1192357
Lesenswert?

TEMP sollte mindestens vom Typ float sein, wenn du sowas wie *0.01 
machst. Ausserdem wäre es schön wenn du TEMP dann z.B. fTemp schreiben 
würdest. In Tempaufnahme() kannst du lokal eine int-Variable 
deklarieren, in die du Bits einliest (anstatt TEMP) und dann den 
Temp-Wert vom Sensor zurücklieferst. Den zurückgelieferten Wert 
übergibst du dann Temp_umrechnung().
Liefert der SHT nicht noch eine Prüfsumme die geprüft werden sollte?


float Temp_umrechnung( unsigned int uiMesswert)
{
return( ( float)uiMesswert * 0.01f - 40.0f);
}
Gast #1193240
Lesenswert?

Hallo,

die Umrechnung ist kein Problem.
Und ein Floatwert ist auch erst bei der Rechnung notwendig.
Mein Problem liegt aber schon darin dass der 16 Bit Integer Wert (TEMP) 
schon gar nicht richtig ausgelesen wird. (per JTAG)
Es kommt ein viel zu hoher Wert raus, sodass ich beim ausrechnen der 
Temp. per Taschenrechner schon auf knapp 100Grad komme.
Ich vermute es ist ein Timing Problem, bzw. dass irgendwo ein "Takt" 
vergessen wurde, konnte aber nichts finden ;(

Schönen Samstag noch..
GAST

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren