DS18S20 Temperatur lesen / Timing

OP #2737509
Hallo

Ich habe einen DS18S20 am ATMEGA8 geschaltet.

DQ uber pullup zu PB1.

Mein reset Routine funtioniert, ich bekomme den Presence Pulse zuruck 
(Bus low), danach mochte ich ein SKIP ROM (0xCC) Befehl senden und eine 
Temperaturmessung durch Convert T (0x44) starten. Ich warte bis die 
Temperaturmessung beended ist. Danach versuche ich uber den READ 
SCRATCHPAD Befehl die ersten zwei Bytes des Scratchpad auszulesen.

Leider bekomme ich beide Bytes als 0x00 zuruck.

Irgendwo ist der Wurm drin:
1
#define F_CPU 1000000
2
#include <avr/io.h>
3
#include "lcd-routines.h"
4
#include <util/delay.h>
5

6
void delay_us ( uint8_t us )
7
{
8
  for(; us > 0; us--) _delay_us(1);
9
}
10

11
int ow_reset(void){
12
  DDRB |= (1<<PB1);
13
  PORTB &= ~(1<<PB1);
14
  _delay_us(480);
15
  DDRB &= ~(1<<PB1);
16
  _delay_us(80);
17
  while((PINB & (1<<PINB1))){
18

19
  }
20
  return 1;
21
}
22

23
uint8_t ow_write_byte(uint8_t value){
24
  uint8_t i      = 0;
25
  uint8_t pulse  = 0;
26

27
  for(i=0; i<8; i++){                   // 8 bits
28
    if(value & (1<<i)){
29
      pulse = 1;                        // 5us for logic 1
30
    } else {
31
      pulse = 100;                      // 100us for logic 0
32
    }
33
    DDRB |= (1<<PB1);                   // DQ Low
34
    PORTB &= ~(1<<PB1);
35
    delay_us(pulse);                    // send bit
36
    DDRB &= ~(1<<PB1);
37
    delay_us(120-pulse);                // fill up frame
38
    delay_us(10);                       // recovery period
39
  };
40
  return 1;
41
}
42

43
void main(void)
44
{
45
  lcd_init();
46
  ow_reset();
47
  ow_write_byte(0xCC);
48
  ow_write_byte(0x44);
49
  _delay_ms(1000);
50
  ow_reset();
51
  ow_write_byte(0xCC);
52
  ow_write_byte(0xBE);
53

54
  lcd_string("TEMP");
55
  ow_read_byte();
56
  ow_read_byte();
57
}
58

59

60
int ow_read_byte(void){
61
  uint8_t i = 0;
62

63
  for(i=0;i<8;i++){
64
    DDRB |= (1<<PB1);
65
    PORTB &= ~(1<<PB1);
66
    _delay_us(1);
67
    PORTB &= ~(1<<PB1);
68
    DDRB &= ~(1<<PB1);
69
    _delay_us(5);
70
    if((PINB & (1<<PINB))){
71
      lcd_string("1");
72
    }else{
73
      lcd_string("0");
74
    }
75
  }
76
  _delay_us(5);
77
  return 0;
78
}

Weiss Jemand Rat ?

Grus
OP #2737634
holger schrieb:
> Da isser der Wurm;)
>
>     PORTB &= ~(1<<PB1);
>     _delay_us(1);
>     PORTB &= ~(1<<PB1);

Ich kann leider nicht folgen:
1
int ow_read_byte(void){
2
  uint8_t i = 0;
3

4
  for(i=0;i<8;i++){
5
    DDRB |= (1<<PB1);
6
    PORTB &= ~(1<<PB1);
7
    _delay_us(1);
8
    DDRB &= ~(1<<PB1);
9
    _delay_us(5);
10
    if((PINB & (1<<PINB))){
11
      lcd_string("1");
12
    }else{
13
      lcd_string("0");
14
    }
15
  }
16
  _delay_us(5);
17
  return 0;
18
}
Gast #2737644
>Ich kann leider nicht folgen:

Ich auch nicht, aber das zweite PORTB... ist überflüssig.

Aber da solltest du noch mal GENAU hinsehen:

    if((PINB & (1<<PINB))){
      lcd_string("1");
     }else{
      lcd_string("0");
    }
OP #2737661
danke @holger
1
int ow_read_byte(void){
2
  uint8_t i = 0;
3

4
  for(i=0;i<8;i++){
5
    DDRB |= (1<<PB1);
6
    PORTB &= ~(1<<PB1);
7
    _delay_us(1);
8
    DDRB &= ~(1<<PB1);
9
    _delay_us(5);
10
    if(PINB & (1<<PINB1)){
11
      lcd_string("1");
12
    }else{
13
      lcd_string("0");
14
    }
15
  }
16
  _delay_us(5);
17
  return 0;
18
}

Jetzt kriege ich aber lauter "1", 0xFF ausgelesen.

Das Default Value ist ja 0x00AA (Datenblatt)

Ich poste mal das komplette program im jetzigem Zustand:
1
#define F_CPU 1000000
2
#include <avr/io.h>
3
#include "lcd-routines.h"
4
#include <util/delay.h>
5

6
void delay_us ( uint8_t us )
7
{
8
  for(; us > 0; us--) _delay_us(1);
9
}
10

11
int ow_reset(void){
12
  DDRB |= (1<<PB1);
13
  PORTB &= ~(1<<PB1);
14
  _delay_us(480);
15
  DDRB &= ~(1<<PB1);
16
  _delay_us(80);
17
  while((PINB & (1<<PINB1))){
18

19
  }
20
  return 1;
21
}
22

23
uint8_t ow_write_byte(uint8_t value){
24
  uint8_t i      = 0;
25
  uint8_t pulse  = 0;
26

27
  for(i=0; i<8; i++){                   // 8 bits
28
    if(value & (1<<i)){
29
      pulse = 1;                        // 5us for logic 1
30
    } else {
31
      pulse = 100;                      // 100us for logic 0
32
    }
33
    DDRB |= (1<<PB1);                   // DQ Low
34
    PORTB &= ~(1<<PB1);
35
    delay_us(pulse);                    // send bit
36
    DDRB &= ~(1<<PB1);
37
    delay_us(120-pulse);                // fill up frame
38
    delay_us(10);                       // recovery period
39
  };
40
  return 1;
41
}
42

43
void main(void)
44
{
45
  lcd_init();
46
  ow_reset();
47
  ow_write_byte(0xCC);
48
  ow_write_byte(0x44);
49
  _delay_ms(1000);
50
  ow_reset();
51
  ow_write_byte(0xCC);
52
  ow_write_byte(0xBE);
53

54
  lcd_string("TEMP");
55
  ow_read_byte();
56
  ow_read_byte();
57
}
58

59

60
int ow_read_byte(void){
61
  uint8_t i = 0;
62

63
  for(i=0;i<8;i++){
64
    DDRB |= (1<<PB1);
65
    PORTB &= ~(1<<PB1);
66
    _delay_us(1);
67
    DDRB &= ~(1<<PB1);
68
    _delay_us(5);
69
    if(PINB & (1<<PINB1)){
70
      lcd_string("1");
71
    }else{
72
      lcd_string("0");
73
    }
74
  }
75
  _delay_us(5);
76
  return 0;
77
}
OP #2737804
Ich habe es noch etwas "aufpoliert", es ist mehr lesbar und einfacher zu 
andern. Leider bleibt der Fehler bestehen. Am DS18S20 kann es nicht 
liegen, weil ich ein Paar davon habe, und bei allen der Fehler 
auftaucht.

Also der Fehler: Ich kriege lauter "1" gelesen.
1
#define F_CPU 1000000
2
#include <avr/io.h>
3
#include "lcd-routines.h"
4
#include <util/delay.h>
5

6
void delay_us ( uint8_t us )
7
{
8
  for(; us > 0; us--) _delay_us(1);
9
}
10

11
void dq_low(uint8_t period){
12
  DDRB |= (1<<PB1);
13
  PORTB &= ~(1<<PB1);
14
  delay_us(period);
15
  DDRB &= ~(1<<PB1);
16
}
17

18
int ow_reset(void){
19
  dq_low(480);
20
  _delay_us(80);
21
  while((PINB & (1<<PINB1))){
22

23
  }
24
  _delay_us(300);
25
  return 1;
26
}
27

28
uint8_t ow_write_byte(uint8_t value){
29
  uint8_t i      = 0;
30

31
  for(i=0; i<8; i++){
32
    if(value & (1<<i)){
33
      dq_low(1);
34
      delay_us(115);
35
    } else {
36
      dq_low(100);
37
      delay_us(10);
38
    }
39
  };
40
  delay_us(50);
41
  return 1;
42
}
43

44
uint8_t ow_read_byte(void){
45
  uint8_t i = 0;
46
  uint8_t result = 0;
47

48
  for(i=0;i<8;i++){
49
    dq_low(2);
50
    _delay_us(14);
51
    if(PINB & (1<<PINB1)){
52
      result |= (1<<i);
53
    }
54
    _delay_us(1);
55
  }
56
  return result;
57
}
58

59

60
int main(void)
61
{
62
  uint8_t s0 = 0;
63
  uint8_t s1 = 0;
64

65
  lcd_init();
66
  ow_reset();
67
  ow_write_byte(0xCC);
68
  ow_write_byte(0xBE);
69
  s0 = ow_read_byte(); // = 0xFF - WHY ?!
70
  s1 = ow_read_byte(); // = 0xFF - WHY ?!
71

72
  ow_reset();
73
  
74
  lcd_setcursor(0,1);
75
  lcd_byte_binary(s0);
76
  lcd_setcursor(0,2);
77
  lcd_byte_binary(s1);
78

79
  return 1;
80
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.