Hallo,
ich habe mir zum Auslesen eines DS18S20 ein kleines Programm
geschrieben. Am Bus hängt nur ein Sensor und er wird mit eigener
Versorgung betrieben.
Wenn ich dem Sensor das Reset-Signal sende, danach "Skip rom" und danach
die Temperatur lese, bekomme ich erwartungsgemäß 0xAA (85°C) zurück.
Wenn ich zuvor allerdings die Temperaturmessung (Befehl 0x44) starte und
warte, bis der Sensor eine "1" auf die Datenleitung zurückgibt (warten
auf fertige Wandlung), lese ich danach immer 0x2B als Temperatur aus
(entspricht 53°C, bei Raumtemperatur..). Habe ich etwas falsch gemacht
oder ist der Sensor kaputt?
Ich habe ihn nämlich einmal versehentlich verpolt angeschlossen.
Anbei noch ein Auszug aus einem Mitschnitt des Ports mit Logic analyzer,
mit dessen Hilfe ich derzeit noch die Werte auslese.
Danke im Voraus,
Adrian
Hier der Code:
1 | /*
|
2 | * temperatur.c
|
3 | *
|
4 | * Created: 05.04.2014 12:28:24
|
5 | * Author: Adrian
|
6 | */
|
7 |
|
8 | #define F_CPU 8000000UL
|
9 | #include <avr/interrupt.h>
|
10 | #include <avr/io.h>
|
11 |
|
12 | #define DELAY(x) (x<<3)
|
13 | #define INPUT_HIGH() (1&(PINB>>PB0))
|
14 | #define PULL() (DDRB |= (1<<PB0))
|
15 | #define RELEASE() (DDRB &= ~(1<<PB0))
|
16 |
|
17 | void setup(void) {
|
18 | DDRB = 0;
|
19 | PORTB = 0;
|
20 |
|
21 | TCCR1B = (1<<CS10); // 8MHz
|
22 | }
|
23 |
|
24 | void delay_us(uint16_t amount) {
|
25 | uint16_t comp = TCNT1;
|
26 | while ((uint16_t)(TCNT1-comp) <= DELAY(amount)){;}
|
27 | }
|
28 |
|
29 | void reset() {
|
30 | PULL();
|
31 | delay_us(500);
|
32 | RELEASE();
|
33 | }
|
34 |
|
35 | uint8_t read_bit() {
|
36 | uint8_t bit_val;
|
37 | delay_us(1);
|
38 | PULL();
|
39 | delay_us(1);
|
40 | RELEASE();
|
41 | delay_us(14);
|
42 | bit_val = INPUT_HIGH();
|
43 | delay_us(46);
|
44 | return bit_val;
|
45 | }
|
46 |
|
47 | uint8_t read_mul_bits (uint8_t amount) {
|
48 | uint8_t val = 0;
|
49 | for (uint8_t i=0; i<amount; i++) {
|
50 | val |= read_bit()<<i;
|
51 | }
|
52 | return val;
|
53 | }
|
54 |
|
55 | void write_bit(uint8_t bit) {
|
56 | delay_us(1);
|
57 | PULL();
|
58 | if(bit) {
|
59 | delay_us(15);
|
60 | RELEASE();
|
61 | delay_us(60-15);
|
62 | } else {
|
63 | delay_us(60);
|
64 | RELEASE();
|
65 | }
|
66 | }
|
67 |
|
68 | void write_byte(uint8_t byte) {
|
69 | for (uint8_t i=0; i<8; i++) {
|
70 | write_bit(1&byte>>i);
|
71 | }
|
72 |
|
73 | }
|
74 |
|
75 | int main(void)
|
76 | {
|
77 | setup();
|
78 |
|
79 | reset();
|
80 | delay_us(200); // presence abwarten
|
81 | write_byte(0xCC); //skip rom
|
82 | write_byte(0x44); // start t conv
|
83 | while(read_bit()==0){;} // warten auf conv ende
|
84 | delay_us(500); // zusätzlich warten, nur zur sicherheit
|
85 |
|
86 | reset();
|
87 | delay_us(200);
|
88 | write_byte(0xCC);
|
89 | write_byte(0xBE); // speicher lesen
|
90 | read_mul_bits(16); // erste zwei byte
|
91 |
|
92 | while(1)
|
93 | {}
|
94 | }
|