Hallo,
ich weiß, über die DS1820 wurde schon viel geschieben. Auch ich habe ein
Problem mit der Ansteuerung. Ich verwende einen Mega32 mit externem 4MHZ
Quarz.
Der DS18B20 hängt an PD6. An PD5 habe ich eine PWM laufen. (macht das
was?)
Ich möchte einfach nur die Temperatur auslesen.
Ich verwende nicht den Power-Parasite-Mode.
Hier die Funktionen:
1
voidbus_o()
2
{
3
DDRD|=(1<<PD6);
4
}
5
6
voidbus_i()
7
{
8
DDRD&=~(1<<PD6);
9
}
10
11
voidbus_write(uint32_ta)
12
{
13
chardata[20];
14
itoa(a,data,2);
15
char*s;
16
s=data;
17
18
while(*s!='\0')
19
{
20
if(*s=='1')
21
{
22
bus_o();
23
_delay_us(14);
24
bus_i();
25
_delay_us(70);
26
}
27
28
if(*s=='0')
29
{
30
bus_o();
31
_delay_us(100);
32
bus_i();
33
_delay_us(2);
34
}
35
36
s++;
37
38
_delay_us(2);
39
}
40
}
41
42
intbus_read(intanz_bits)
43
{
44
intt;
45
charT[20];
46
inti=0;
47
48
while(i<anz_bits)
49
{
50
bus_o();
51
_delay_us(1.1);
52
bus_i();
53
_delay_us(10);
54
55
if((PIND&0b01000000)==0)
56
{
57
T[i]=0;
58
}
59
60
if((PIND&0b01000000)==1)
61
{
62
T[i]=1;
63
}
64
65
while((PIND&0b01000000)==0)
66
{
67
}
68
69
_delay_us(2);
70
71
i++;
72
}
73
74
t=atoi(T);
75
76
returnt;
77
}
78
79
voidtemperature_get()
80
{
81
//this function reads the temperature from the DS1820
82
83
bus_i();
84
85
//init...
86
_delay_ms(1);
87
bus_o();
88
_delay_us(480);
89
bus_i();
90
_delay_ms(1);
91
92
bus_write(0xCC);//Skip-ROM, da ich nur einen 1-wire-device habe...
93
_delay_ms(1);
94
bus_write(0x44);//Convert T
95
_delay_ms(1);
96
97
temperature=bus_read(9);
98
}
Die Funktion "temperature_get()" wird alle 3 sec. aufgerufen. Die
Variabel "temperature" ist eine globale int.
Leider bleibt der Wert von "temperature" immer bei 0
Was mache ich falsch?
Gruß
georg
> T[i] = 0;> T[i] = 1;
0 ist nicht gleich '0'
1 ist nicht gleich '1'
> t = atoi(T);
atoi macht aus "101" den Wert 101 und nicht 5.
Und itoa ist nicht für 32 bit Variablen geeignet.
Hallo,
ich habe das Programm nochmals neu überarbeitet und das kam dabei raus:
1
voidbus_o()
2
{
3
DDRD|=(1<<PD6);
4
}
5
6
voidbus_i()
7
{
8
DDRD&=~(1<<PD6);
9
}
10
11
voidwrite_bit(intb)
12
{
13
if(b==1)
14
{
15
bus_o();
16
_delay_us(3);
17
bus_i();
18
_delay_us(110);
19
}
20
21
if(b==0)
22
{
23
bus_o();
24
_delay_us(110);
25
bus_i();
26
}
27
28
_delay_us(2);
29
}
30
31
doubleread_bit()
32
{
33
doubleb;
34
35
bus_o();
36
_delay_us(2);
37
bus_i();
38
_delay_us(10);
39
40
b=(PIND&0b01000000);
41
42
_delay_us(110);
43
44
returnb;
45
}
46
47
voidbus_write(uint32_ta,intanz_bits)
48
{
49
intmaske=1;
50
inti=0;
51
52
while(i!=anz_bits)
53
{
54
write_bit(a&maske);
55
maske=maske*2;
56
i++;
57
}
58
}
59
60
intbus_read(intanz_bits)
61
{
62
inti=1;
63
doublet=0;
64
doublex=1;
65
66
while(i!=anz_bits)
67
{
68
t=t+(read_bit()*x);
69
i++;
70
x=x*2;
71
}
72
73
returnt;
74
}
75
76
voidtemperature_get()
77
{
78
//this function reads the temperature from the DS18B20
79
bus_i();
80
81
//init...
82
_delay_ms(1);
83
bus_o();
84
_delay_us(490);
85
bus_i();
86
87
bus_write(0xCC,8);//skip ROM
88
bus_write(0x44,7);//T Convert
89
90
temperature=bus_read(16);
91
}
Jeodch erhalte ich immer 192 als Temperatur zurück... Was mache ich
falsch?
Kann man überhaupt die _delay_us() verwenden oder ist das zu ungenau?
Gruß
georg
georg schrieb:> double read_bit()
Du traust der CPU wohl nicht, also speicherst Du ein einzelnes Bit in
einem 64bit-Float Wert.
4MHz ist schon recht knapp, da sollte man besser nur uint8_t als
Variablen nehmen für den Hardwarezugriff.
Und extra Funktionen fürs Bitsetzen könnte auch zu teuer werden.
Entweder Inline oder als Macro.
Peter
Hallo,
ok, danke für diesen Hinweis! Habe nun am Ende der reset_bus() -
Funktion _delay_ms(1);
Es geht aber immer noch nicht. Was denn nun??? Ich komme einfach nicht
drauf :-(
georg
Hallo,
jetzt habe ich immer eine Temperatur von 336, außer, wenn ich die Masse
vom DS18B20 abklemme, dann habe ich eine Temperatur von 511...
Woran liegt das???
:-(
georg
Hallo,
jetzt geht er!!! (jetzt ändert sich der Wert, wenn ich den DS18B20
erwärme, aber die Werte stimmen nicht.)
Zuvor bei den Werten mit 336 z.B. blieb das konstant.
Seit ich bus_write(0x44, 7); in bus_write(0x44, 8); umgeändert habe,
geht er... wieso das, frage ich mich???
Naja, mit "er geht" meine ich, dass ich endlich was auslesen kann.
Jedoch zeigt er z.B. 168 an. Muss mal mit einem Termomenter vergleichen,
aber ich glaube, das kommt nicht ganz hin.
was hat es denn beim DS18B20 mit der "THERMOMETER RESOLUTION
CONFIGURATION" auf sich????
-georg
Danke für die Hilfe!
georg schrieb:> Naja, mit "er geht" meine ich, dass ich endlich was auslesen kann.> Jedoch zeigt er z.B. 168 an. Muss mal mit einem Termomenter vergleichen,> aber ich glaube, das kommt nicht ganz hin.
Ab und zu mal eine Nacht mit 168 wär jetzt nicht übel, aber auf Dauer
doch etwas zu frisch für Juli. Die 336 gefielen mir besser (als
Ergebnis).
> was hat es denn beim DS18B20 mit der "THERMOMETER RESOLUTION> CONFIGURATION" auf sich????
Für den Anfang erstmal garnix. Kannst damit zwischen langsam/genau und
schnell/ungenau wählen.
Die obige Version von bus_read gefiel mir besser. Das war glaube ich die
einzige Funktion ohne Fehler ;-). Ein Zähler der 4 Mrd Bits lesen kann,
aber für's Ergebnis nur 8 zulässt - nö.
georg schrieb:> ok, ohne Messung kommt bei mir leider 80, also 0x50... Was nun???
Perfekt. Jetzt musst du nur bus_read wieder vom Kopf auf die Füsse
stellen.
Hallo,
ok, wenn ich die bus_read Funktion so habe:
1
intbus_read(intanz_bits)
2
{
3
inti=1;
4
intt=0;
5
intx=1;
6
7
while(i!=anz_bits)
8
{
9
t=t+(read_bit()*x);
10
i++;
11
x=x*2;
12
}
13
14
returnt;
15
}
Dann kommt 1360, also 0x550. Als Temperatur zeigt er aber leider z.B.
bei Raumtemperatur 433 an... Muss ich den das noch durch 16 teilen, weil
im Datenblatt die Tabelle 2: (im Anhang...)
georg
Cool, danke!
Jetzt zeigt er auch 26°C an!!! und mein analog-Tchibo Thermometer
auch!!!
und, wenn ich den Finger drann halte, dann geht er auf ca. 30!!!
Scheint also zu gehen!! freu Und danke nochmals für die tolle Hilfe!
Eine Frage habe ich aber noch: Ich habe jetzt ja einen DS18B 20
drann. Darum muss ich auch die Temperatur noch durch 16 teilen. Wie ist
das aber, wenn ich einen DS18S 20 drann hab??? Durch 2????
georg