Forum: Mikrocontroller und Digitale Elektronik DS1820, Sendet außer Presence nichts zurück.


von Matze (Gast)


Lesenswert?

Hallo,

Habe Probleme damit einen DS1820 Temperatursensor auszulesen, welcher an 
einem Atmega16 hängt.

Er hängt an Port B0, und hat einen 4,7K Ohm-Pullup.

Das Programm sieht zum Reset des DS1820 einen 600us-Low vor, danach 
meldet er sich 28uS später mit einem Presence Pulse von 102uS.
Soweit ist alles OK.

Problem ist nun dass egal was ich an ihn Sende z.b. (0xBE für 
Read-Scratch-Pad oder 0x33 für Read Rom) er nichts zurück Sendet.

Ich Sende ihm 0en der Länge 85uS, einsen der Länge 9uS und gebe ihm ca 
0,5Sek Zeit um die Leitung selbst mal auf Masse zu ziehen.
Aber das tut er ja nicht.
1
ISR(TIMER0_COMP_vect)
2
{
3
  PORTB|=0x01;  //Pin Setzen
4
  TCCR0=0x00;    //Stoppen
5
  Tint=1;
6
  //while(1){;}
7
}
8
9
int main(void)
10
{
11
  Init();
12
  DDRD|=0x40;    //Triggerung
13
  One_Wire_Send(0x55,1);
14
  PORTD|=0x40;
15
  _delay_ms(3);
16
  PORTD&=0xBF;
17
  while(1)
18
    {  
19
    One_Wire_Send(0x44,0);
20
    PORTD|=0x40;
21
    _delay_ms(3);
22
    PORTD&=0xBF;  
23
    One_Wire_Send(0xB4,0);
24
    PORTD|=0x40;
25
    _delay_ms(1);
26
    PORTD&=0xBF;
27
28
    //Stellen();
29
    //Wecken();
30
    }
31
}
32
33
void One_Wire_Send(unsigned short int Byte, int Steuer)
34
{
35
  Tint=0;
36
  DDRB|=0x01;    //PB0 auf Ausgang
37
  TIMSK|=0x02;  //Interrupt Timer0 Enable
38
  unsigned short int Vergleich = 0x80;
39
  if(Steuer==1)  //Reset des DS1820
40
  {
41
    TCNT0=0x00;    //Anfang des Zählens
42
    OCR0=38;    //--600uS
43
    PORTB&=0xFE;  //Pin = 0
44
    TCCR0=0x03;    //Prescaler = 8,Timer Starten --16uS
45
    while(Tint!=1) //warten bis IRQ Ausgelöst
46
    {
47
      ;
48
    }
49
  }
50
  else
51
  {
52
    for(int i=8;i>=1;Vergleich=Vergleich/2, i--)
53
    {
54
      Tint=0;
55
      if(Byte & Vergleich)    //1 Senden
56
      {
57
        TCNT0=0x00;    //Anfang des Zählens
58
        OCR0=0x01;    //--10uS
59
        PORTB&=0xFE;  //Pin = 0
60
      }
61
      else        //0 Senden
62
      {
63
        TCNT0=0x00;    //Anfang des Zählens
64
        OCR0=0x25;    //--90uS
65
        PORTB&=0xFE;  //Pin = 0
66
      }
67
      TCCR0=0x02;    //Prescaler = 8,Timer Starten
68
      while(Tint!=1)
69
      {
70
        ;
71
      }
72
    }  
73
  }    
74
}

Eventuell seht ihr das Problem.

Grüße
Matze

von (prx) A. K. (prx)


Lesenswert?

Und jetzt darf also jeder das Datasheet vorkramen, um rauszukriegen, 
welche Codes 0x55, 0xB4, ... sind?

von (prx) A. K. (prx)


Lesenswert?

Bei 1-Wire darf der µC nie aktiv den Pin hochziehen, ausser in der 
Messphase bei parasitärer Versorgung. Das muss aufgrund der 
bidirektionalen Arbeitsweise ein externer Pullup-Widerstand machen.

Also: PORTB.0=0 lassen und DDRB.0=0 für high/input, DDRB.0=1 für low.

: Bearbeitet durch User
von Route_66 H. (route_66)


Lesenswert?

Matze schrieb:
> Eventuell seht ihr das Problem.

Damit er erkennen kann dass er und nur er gemeint ist, muß er ein Skip 
ROM bekommen, es könnten ja mehrere am Draht hängen. Dann muß man 
nämlich ein Match ROM mit der zugehörigen Adresse senden.

von (prx) A. K. (prx)


Lesenswert?

0x55 = MATCH ROM benötigt danach die Sensor ID. Bei einem einzelnen 
Sensor ist SKIP ROM sinnvoller.

von Matze (Gast)


Lesenswert?

A. K. schrieb:
> Also: PORTB.0=0 lassen und DDRB.0=0 für high/input, DDRB.0=1 für low.

Danke, das hab ich nun erledigt und so geht der Presence auch wirklich 
bis 0V.

Route 66 schrieb:
> Damit er erkennen kann dass er und nur er gemeint ist, muß er ein Skip
> ROM bekommen, es könnten ja mehrere am Draht hängen. Dann muß man
> nämlich ein Match ROM mit der zugehörigen Adresse senden.

Stimmt, die würde eich es überhaupt machen wenn ich mehrere DS1820an 
einem Bus hätte?
Müsste ich sie mit der Sensior-ID Addressieren die ich vermutlich vor 
dem 1. Auslesen mittels Skip-Rom nicht kennen würde?

Das Problem ist jedoch immer noch das selbe, er gibt keine Daten aus.

Wenn ich dem Signalflussdiagramm im Datenblatt folge steht dort zuerst 
kommt ein Reset, danach kann ich ein Skip-Rom (0xCC) senden.

Danach hoffe ich die Temperatur wandeln zu können (0x44) und sie 
auslesen zu können (0xBE).

Habe den Code auch sonst etwas verbessert:
1
ISR(TIMER0_COMP_vect)
2
{
3
  DDRB&=0xFE;    //Pin Setzen / Input
4
  TCCR0=0x00;    //Stoppen
5
  Tint=1;
6
}
7
8
int main(void)
9
{
10
  Init();
11
  DDRD|=0x40;        //Triggerung für Oszi
12
  PORTB&=FE;        //PORTB.0=0
13
  TIMSK|=0x02;      //Interrupt Timer0 Enable
14
  while(1)
15
    {  
16
17
    One_Wire_Send(0x00,1);  //Reset
18
    _delay_ms(2);      //Zeit für Presence = 500uS
19
    One_Wire_Send(0xCC,0);  //DS1820Auswählen
20
    One_Wire_Send(0x44,0);  //Temperatur Wandeln
21
    PORTD|=0x40;      //Setzen
22
    One_Wire_Send(0xBE,0);  //Temperatur Zusenden
23
    _delay_ms(4);      //Zeit zum zusenden
24
    PORTD&=0xBF;      //Rücksetzen
25
    }
26
}
27
28
void One_Wire_Send(unsigned short int Byte, int Steuer)
29
{
30
  Tint=0;
31
  unsigned short int Vergleich = 0x80;
32
  if(Steuer==1)  //Reset des DS1820
33
  {
34
    TCNT0=0x00;    //Anfang des Zählens
35
    OCR0=38;    //--600uS
36
    DDRB|=0x01;    //Portpin auf LOW / Ausgang  
37
    TCCR0=0x03;    //Prescaler = 8,Timer Starten --16uS
38
    while(Tint!=1)  //Warten bis IRQ Ausgelöst
39
    {;}
40
  }
41
  else        //Fals Kein Steuersignal übertragen werden soll
42
  {
43
    for(int i=8;i>=1;Vergleich=Vergleich/2, i--)
44
    {
45
      TCNT0=0x00;    //Anfang des Zählens
46
      Tint=0;
47
      if(Byte & Vergleich)    //1 Senden
48
      {
49
        OCR0=0x01;    //--10uS
50
      }
51
      else        //0 Senden
52
      {
53
        OCR0=0x25;    //--90uS
54
      }
55
      DDRB|=0x01;      //Pin = 0
56
      TCCR0=0x02;      //Prescaler = 8,Timer Starten
57
      while(Tint!=1)    //Warten bis IRQ Ausgelöst
58
      {;}
59
    }  
60
  }    
61
}

von Karl H. (kbuchegg)


Lesenswert?

>     One_Wire_Send(0x44,0);  //Temperatur Wandeln
>     PORTD|=0x40;      //Setzen
>     One_Wire_Send(0xBE,0);  //Temperatur Zusenden
>     _delay_ms(4);      //Zeit zum zusenden

He. Moment mal.
Ich hab jetzt die Codes nicht kontrolliert.
Aber nachdem du dem DS befohlen hast, die Temperatur festzustellen, 
musst du ihm auch Zeit geben, genau das zu tun.

Ehe da jetzt weiter analysiert wird.
In der Codesammlung gibt es Routinen für den DS1820. Im speziellen 
fallen mir die Routinen vom Peter Danegger ein. Hol dir die mal und 
studier mal, wie das alles gedacht ist.

von Matze (Gast)


Lesenswert?

Ich hätte nicht gedacht das er 500mS zum Wandeln braucht.

Ein weiteres Problem war dass nicht einfach 0en und 1en gesendet werden, 
sondern die Kommunikation in Timeslots abläuft.

Ein Timeslot hat eine länge von 60-120uS.

Folglich müssen im Falle einer gesendeten 1 mit 10uS auf Low, zusätzlich 
80uS High folgen bevor das nächste Bit gesendet wird.

Diese Fehler wurden nun Korrigiert.

Eine 0 Besteht aus 80uS LOW und 10uS High.
Eine 1 aus 10uS LOW und 80uS High.

Aber auch das hat am eigentlichen Problem nichts geändert.
Er zieht die Leitung nur auf Low um sein dasein zu bestätigen.

So sieht es nun aus:
1
ISR(TIMER0_COMP_vect)
2
{
3
  DDRB&=0xFE;    //Pin Setzen / Input
4
  TCCR0=0x00;    //Stoppen
5
  Tint=1;
6
}
7
8
int main(void)
9
{
10
  Init();
11
  DDRD|=0x40;        //Triggerung für Oszi
12
  PORTB&=FE;        //PORTB.0=0
13
  TIMSK|=0x02;      //Interrupt Timer0 Enable
14
  while(1)
15
    {  
16
    One_Wire_Send(0x00,1);  //Reset
17
    _delay_ms(2);      //Zeit für Presence = 500uS
18
    One_Wire_Send(0xCC,0);  //DS1820 Auswählen
19
    _delay_ms(1);      //Zeit zum Wandeln
20
    One_Wire_Send(0x44,0);  //Temperatur Wandeln
21
    _delay_ms(600*4);    //Zeit zum Wandeln 600ms
22
    //One_Wire_Send(0xCC,0);  //DS1820 Auswählen
23
    _delay_ms(2);      //Zeit zum Wandeln
24
    while(1)
25
    {
26
      One_Wire_Send(0x00,1);  //Reset
27
      _delay_ms(2);      //Zeit für Presence = 500uS
28
      PORTD|=0x40;      //Setzen
29
      One_Wire_Send(0x33,0);  //Temperatur Zusenden
30
      _delay_ms(10);      //Zeit zum zusenden
31
      PORTD&=0xBF;      //Rücksetzen
32
    }
33
34
    }
35
}
36
37
void One_Wire_Send(unsigned short int Byte, int Steuer)
38
{
39
40
  unsigned short int Vergleich = 0x80;
41
  if(Steuer==1)  //Reset des DS1820
42
  {  
43
    Tint=0;
44
    TCNT0=0x00;    //Anfang des Zählens
45
    OCR0=38;    //--600uS
46
    DDRB|=0x01;    //Portpin auf LOW / Ausgang  
47
    TCCR0=0x03;    //Prescaler = 8,Timer Starten --16uS
48
    while(Tint!=1)  //Warten bis IRQ Ausgelöst
49
    {;}
50
  }
51
  else        //Fals Kein Steuersignal übertragen werden soll
52
  {
53
    for(int i=8;i>=1;Vergleich=Vergleich/2, i--)
54
    {
55
      Tint=0;
56
      TCNT0=0x00;    //Anfang des Zählens
57
      if(Byte & Vergleich)  //1 Senden
58
      {
59
        OCR0=0x01;      //--10uS
60
        DDRB|=0x01;      //Pin = 0
61
        TCCR0=0x02;      //Prescaler = 8,Timer Starten      
62
        while(Tint!=1)    //Warten bis IRQ Ausgelöst
63
        {;}  
64
        Tint=0;  
65
        TCNT0=0x00;      //Zähler=0
66
        OCR0=0x1A;      //80uS für 90uS - Timeslot
67
        TCCR0=0x02;      //Prescaler = 8,Timer Starten
68
        while(Tint!=1)  {;}  //Warten bis IRQ Ausgelöst      
69
      }
70
      else          //0 Senden
71
      {
72
        OCR0=0x25;      //--90uS
73
        DDRB|=0x01;      //Pin = 0
74
        TCCR0=0x02;      //Prescaler = 8,Timer Starten
75
        while(Tint!=1){;}    //Warten bis IRQ Ausgelöst
76
      }
77
    }  
78
  }    
79
}

von Klaus (Gast)


Lesenswert?

@Matze

Das hier wird dir helfen sofer der Link funktioniert.
http://www.mikrocontroller.net/attachment/93011/1-Wire-Projekt-V1_3.zip

von Matze (Gast)


Angehängte Dateien:

Lesenswert?

@Klaus

Danke das Projekt ist sehr nützlich,

Darin steht dass der DS1820 die Daten 15uS nach dem beginn des LOWs bei 
senden einer 1 abgreift.
Um nun sicher zu gehen dass er auch wirklich eine 1 erkennt, habe ich 
das LOW auf 8uS verkürzt.
Ausserdem bin ich nun nur noch bei ca 62uS für einen Timeslot und habe 
die Timerinitialisierung ausgelagert.

Laut der Beschreibung des Projekts sendet ein einzelner Slave am Bus, 
nach Reset und Empfang von 0x33 für Read Rom seine 64Bit - ID.

Das müsste wohl noch am ehesten Funktionieren.

Soweit ich gelesen habe muss ich beim 1Wire-Bus das LSB zuerst senden?

Aber auch das alles hat mich noch nicht weiter gebracht.

1
ISR(TIMER0_COMP_vect)
2
{
3
  DDRB&=0xFE;    //Pin Setzen / Input
4
  TCCR0=0x00;    //Stoppen
5
  Tint=1;
6
}
7
8
int main(void)
9
{
10
  Init();
11
  DDRD|=0x40;        //Triggerung für Oszi
12
  PORTB&=FE;        //PORTB.0=0
13
  TIMSK|=0x02;      //Interrupt Timer0 Enable
14
  while(1)
15
    {  
16
      One_Wire_Send(0x00,1);  //Reset
17
      _delay_ms(2);      //Zeit für Presence = 500uS
18
      PORTD|=0x40;      //Setzen
19
      One_Wire_Send(0xCC,0);  //Temperatur Zusenden
20
      _delay_ms(10);      //Zeit zum zusenden
21
      PORTD&=0xBF;      //Rücksetzen
22
      _delay_ms(10);      //Zeit zum zusenden
23
    }
24
}
25
26
void One_Wire_Send(unsigned short int Byte, int Steuer)
27
{
28
  if(Steuer==1)  //Reset des DS1820
29
    Timer0(38,0x03,0);
30
  else        //Fals Kein Steuersignal übertragen werden soll
31
  {  
32
    unsigned short int Vergleich = 0x80;
33
    for(int i=8;i>=1;Vergleich=Vergleich/2, i--)
34
    {
35
      if(Byte & Vergleich)  //1 Senden
36
      {
37
        Timer0(0x02,0x01,0);//Pin ist nach 8 uS wieder auf High
38
        Timer0(0x0A,0x02,1);//ca 55 us Warten      
39
      }
40
      else          //0 Senden
41
      {
42
        Timer0(0x1C,0x02,0);//63 uS LOW
43
      }
44
    }  
45
  }    
46
}
47
48
void Timer0(short unsigned int Zeit,short unsigned int Prescaler, short unsigned int Reset)
49
{
50
  Tint=0;  
51
  TCNT0=0x00;      //Timer auf 0
52
  OCR0=Zeit;      
53
  if(Reset==0)
54
    DDRB|=0x01;    //Portpin auf LOW / Ausgang  
55
  TCCR0=Prescaler;
56
  while(Tint!=1){;}  //Warten bis IRQ Ausgelöst  
57
}

von Matze (Gast)


Lesenswert?

Wenn ich nun wie im PDF des 1-Wire Projekts dem DS1820 zuerst ein
1. Reset
2. Skip-Rom
3. Messung
4. Reset
5. Skip-Rom
6. Read Scratscpad-Ram
sende.

Gibt er außer dem Presence nichts her.

Keine Ahnung was ich tun soll?
1
ISR(TIMER0_COMP_vect)
2
{
3
  DDRB&=0xFE;    //Pin Setzen / Input
4
  TCCR0=0x00;    //Stoppen
5
  Tint=1;
6
}
7
8
int main(void)
9
{
10
  Init();
11
  DDRD|=0x40;        //Triggerung für Oszi
12
  PORTB&=FE;        //PORTB.0=0
13
  TIMSK|=0x02;      //Interrupt Timer0 Enable
14
  One_Wire_Send(0x00,1);  //Reset
15
  _delay_ms(2);      //Zeit für Presence = 500uS
16
  One_Wire_Send(0x44,0);  //Temperatur Wandeln
17
  _delay_ms(750*4);    //Zeit zum Wandeln 600ms
18
  while(1)
19
  {
20
    One_Wire_Send(0x00,1);  //Reset
21
    _delay_ms(2);      //Zeit für Presence = 500uS
22
    PORTD|=0x40;      //Setzen
23
    One_Wire_Send(0xCC,0);  //DS1820 Auswählen
24
    One_Wire_Send(0xBE,0);  //DS1820 Auswählen
25
    _delay_ms(10);      //Zeit zum Wandeln
26
    PORTD&=0xBF;      //Rücksetzen
27
  }
28
}
29
30
void One_Wire_Send(unsigned short int Byte, int Steuer)
31
{
32
  if(Steuer==1)  //Reset des DS1820
33
    Timer0(2);
34
  else        //Fals Kein Steuersignal übertragen werden soll
35
  {  
36
    unsigned short int Vergleich = 0x80;
37
    for(int i=8;i>=1;Vergleich=Vergleich/2, i--)
38
    {
39
      if(Byte & Vergleich)  //1 Senden
40
      {
41
        Timer0(1);    
42
      }
43
      else          //0 Senden
44
      {
45
        Timer0(0);
46
      }
47
    }  
48
  }    
49
}
50
51
void Timer0(int sequenz)  //0 = 0 / 1 = 1 / 2 = Reset
52
{
53
  Tint=0;  
54
  TCNT0=0x00;      //Timer auf 0
55
  switch(sequenz)
56
  {
57
    case 0:      //0 Senden
58
      OCR0=0x1C;
59
      DDRB|=0x01;    //Portpin auf LOW / Ausgang
60
      TCCR0=0x02;
61
      while(Tint!=1){;}  //Warten bis IRQ Ausgelöst
62
    break;
63
    case 1:      //1 Senden
64
      OCR0=0x02;
65
      DDRB|=0x01;    //Portpin auf LOW / Ausgang
66
      TCCR0=0x01;
67
      while(Tint!=1){;}  //Warten bis IRQ Ausgelöst
68
      Tint=0;
69
      TCNT0=0x00;      //Timer auf 0
70
      OCR0=0x0A;
71
      TCCR0=0x02;
72
      while(Tint!=1){;}  //Warten bis IRQ Ausgelöst
73
    break;
74
    case 2:      //Reset
75
      OCR0=38;
76
      DDRB|=0x01;    //Portpin auf LOW / Ausgang
77
      TCCR0=0x03;
78
      while(Tint!=1){;}  //Warten bis IRQ Ausgelöst
79
    break;
80
  }
81
}

von (prx) A. K. (prx)


Lesenswert?

Nach 0xBE sollte der µC das Scratchpad auslesen. Sehe ich hier nicht.

von Эраст Петрович Фандорин (Gast)


Lesenswert?

>Sendet außer Presence nichts zurück.

Zitat Alison Moyet:
"I go weak in the presence of beauty"

von Matze (Gast)


Lesenswert?

@A.K.

Ich sehe mit dem Oszi das der nichts sendet.
Also brauche ich wohl keine Einleseroutine schreiben.

von (prx) A. K. (prx)


Lesenswert?

Matze schrieb:
> Ich sehe mit dem Oszi das der nichts sendet.
> Also brauche ich wohl keine Einleseroutine schreiben.

Bis ein 1-Wire Slave etwas sendet kannst du ewig warten.
Der Master holt es ab.

von Klaus (Gast)


Lesenswert?

@Matze
>Er hängt an Port B0, und hat einen 4,7K Ohm-Pullup.
Wo ist der denn in deinem Schaltplan eingezeichnet?

Für mich sieht es eher aus als würde der DS1820 auf dem Port PB3 
verbunden zu sein. Korrigier mich!

von Klaus (Gast)


Lesenswert?

@Matze

Warum benutzt du Timer Interrupt?

Kein Interrupt während dem Senden und Empfangen von Daten ist schon mal 
der erste Tipp.

von Klaus (Gast)


Lesenswert?

@Matze

Äh! Wo ist der Codeschnipsel Init();

von Matze (Gast)


Lesenswert?

@ A.K.

Ich wusste nicht das der Master die Daten abholen muss.

In diesem
http://www.atmel.com/Images/doc2579.pdf
Datenblatt steht um Daten zu lesen muss der Master den Pin für 1-15uS 
auf LOW ziehen.
Danach kann der Slave die Datenleitung weiterhin aktiv auf LOW ziehenund 
dem Master damit 0en senden.

@Klaus

1.
Stimmt im Schaltplan Hängt der DS1820 auf PinB3.
Ich habe den Schaltplan gezeichnet nach dem ich die "Uhr" aufgebaut 
hatte.
Dabei hat sich herausgestellt, dass es Layouttechnisch besser ist den 
DS1820 auf PB3 zu legen.

Auf dem Lochraster-Prototyp ist er auf PB0.

2.
Stimmt eigentlich kann ich auf den Interrupt verzichten, und es 
stattdessen mit einem Delay machen.
Und im uS-Bereich ist das vielleicht auch praktischer.
Wollte es ursprünglich mit Interrupts machen um sicherzustennen das Uhr 
mit Zeitmultiplexing nicht stehen bleibt.

3.
Der Codeschnipsel Init tut nichts was momentan wichtig ist.

Das Gesamtprogramm ist nun:
1
int main(void)
2
{
3
  Init();
4
  DDRD|=0x40;        //Triggerung für Oszi
5
  PORTB&=FE;        //PORTB.0=0
6
  TIMSK|=0x02;      //Interrupt Timer0 Enable
7
  One_Wire_Send(0x00,1);  //Reset
8
  _delay_ms(2);      //Zeit für Presence = 500uS
9
  One_Wire_Send(0x22,0);  //Temperatur Wandeln
10
  _delay_ms(750*4);    //Zeit zum Wandeln 600ms
11
  while(1)
12
  {
13
    One_Wire_Send(0x00,1);  //Reset
14
    _delay_ms(2);      //Zeit für Presence = 500uS
15
    One_Wire_Send(0x33,0);  //Skip-Rom
16
    PORTD&=0xBF;      //Rücksetzen
17
    One_Wire_Send(0x7D,0);  //Daten Lesen
18
    PORTD|=0x40;      //Setzen
19
    One_Wire_Send(0xFF,0);  //DS1820 Auswählen
20
    PORTD&=0xBF;      //Rücksetzen
21
    One_Wire_Send(0xFF,0);  //DS1820 Auswählen
22
    PORTD|=0x40;      //Setzen
23
    One_Wire_Send(0xFF,0);  //DS1820 Auswählen
24
    One_Wire_Send(0xFF,0);  //DS1820 Auswählen
25
    One_Wire_Send(0xFF,0);  //DS1820 Auswählen
26
    One_Wire_Send(0xFF,0);  //DS1820 Auswählen
27
    One_Wire_Send(0xFF,0);  //DS1820 Auswählen
28
    One_Wire_Send(0xFF,0);  //DS1820 Auswählen
29
  }
30
}
31
32
void One_Wire_Send(unsigned short int Byte, int Steuer)
33
{
34
  if(Steuer==1)  //Reset des DS1820
35
    Bit_Senden(2);
36
  else        //Fals Kein Steuersignal übertragen werden soll
37
  {  
38
    unsigned short int Vergleich = 0x80;
39
    for(int i=8;i>=1;Vergleich=Vergleich/2, i--)
40
    {
41
      if(Byte & Vergleich)  //1 Senden
42
      {
43
        Bit_Senden(1);    
44
      }
45
      else          //0 Senden
46
      {
47
        Bit_Senden(0);
48
      }
49
    }  
50
  }    
51
}
52
53
void Init()
54
{
55
  TCNT1H=0x00;  //Timer auf  0
56
  TCNT1L=0x00;
57
  OCR1A = 15624;
58
  TCCR1A=0x00;  //Kein WPM  / Keine Ansteuerung von Pins
59
  sei();
60
  TIMSK |= (1<<OCIE1A);    //Interrupt Enable
61
  //TCCR1B=0x0C;  //=00001100  / CTC-Modus, Prescaler = 256, Starten
62
  DDRA=0xFF;
63
  DDRB=0x00;    //Eingang
64
  DDRC=0xFC;
65
  DDRD=0x00;
66
}


Nun Funktioniert es :)

Er gibt mir in den ersten 2 Bytes 01010101 00000000
Nun bin ich mit nur noch nicht so richtig sicher wie ich das 
interpretieren soll.
00000000 ist im zum glück positiven Bereich.

Aber 01010101 bedeitet bei +1 Pro 0.5°C für LSB zuletzt 42,5°C
und für LSB zuerst: 85°C.

Beides ist nicht so richtig realistisch.
Denke ich jetzt falsch?

von Klaus (Gast)


Lesenswert?

>Der Codeschnipsel Init tut nichts was momentan wichtig ist.
Sag soetwas nicht Leichtsinnig.

Wie sieht den Bit_Senden(1);   genau aus.
wird dort das Timing der Zeitschlitze eingehalten.

Ein Beispiel wie es Aussehen könnte wenn du Skip-Rom verwendest.
Hier mal ein Codesipsel von mir.
void DS18S20_readrom (void)
{

  uint8_t i;

  DS18S20_writebyte(0xCC);  // Sende Skip ROM - Command
  DS18S20_Init();
  DS18S20_writebyte(0x33);  // Sende READ-ROM - Command
  for(i=0; i<8; i++)
  {
    DS18S20_ROM[i] = DS18S20_readbyte();
  }


}

Als Ergebnis steht dann z.B. in DS18S20_ROM folgendes:

10 0E 61 DD 01 08 00 75  Das ist der Familliencode komplett

von Klaus (Gast)


Lesenswert?

So sieht es aus wenn ich die Temperatur auslesen möchte.

DS18S20_writebyte(0xCC);  // Sende Skip ROM - Command
      DS18S20_Conv_T();
      DS18S20_Init();
      DS18S20_writebyte(0xCC);  // Sende Skip ROM - Command

      DS18S20_writebyte(0xBE);  // Sende Read Scratchpad Command
      for(i=0; i<9; i++)
      {
          DS18S20_Scratchpad[i] = DS18S20_readbyte();
      }

von (prx) A. K. (prx)


Lesenswert?

85° stünde für "kein Wert", wie das Datasheet in schönster Klarheit 
vermittelt.

Wird der Sensor parasitär versorgt, oder mit separatem Vcc?

Wärs nicht allmählich an der Zeit, mal Code anderer Leute anzusehen? 
Mittlerweile ist ohnehin das halbe Programm nicht mehr von dir.

von Matze (Gast)


Angehängte Dateien:

Lesenswert?

@A.K.

Der Sensor wird Separat versorgt.

Ich kann den Sensor nun auslesen, die Temparatur ausrechnen und 
anzeigen.

Habe das Programm nun in eine Main.c und eine DS1820.c sowie DS1820.h 
aufgeteilt.

Eine Erkennung für den Fall das sich der DS1820 nach Reset nicht meldet 
eingebaut.

Nun möchte ich noch die CRC-Prüfsumme berechnen.

Dann soll er mit der Uhr gemeinsam laufen.
Damit diese ganau wird soll später über I2C ein DS3231 (RTC mit TCXO) 
dazukommen.

Mich stört noch das der Sensor 500mS zum wandeln braucht.
Währenddessen soll die Anzeige nicht einfach stehen bleiben, eventuell 
lässt sich das mit einem Timer lösen?

Grüße
Matze

von chris (Gast)


Lesenswert?

Matze schrieb:
> Mich stört noch das der Sensor 500mS zum wandeln braucht.
> Währenddessen soll die Anzeige nicht einfach stehen bleiben, eventuell
> lässt sich das mit einem Timer lösen?

du musst ja nicht warten, während der Sensor misst.
Starte einfach am Anfang die erste Messung.
In der Hauptschleife holst du dann z.B. alle 5-10 Sek. (häufiger ist bei 
Temp. eigentlich selten sinnvoll) den letzten Wert ab und startest die 
nächste Messung. Dein Messwert ist dann zwar jeweils um 4-9 Sekunden 
veraltet, aber das ist wie gesagt bei Temperaturen meistens unwichtig.

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
Noch kein Account? Hier anmelden.