Forum: Mikrocontroller und Digitale Elektronik DS1820 Beispielprogramm in C für EasyAVR5 Board


von RobertP (Gast)


Lesenswert?

Hallo,
obwohl hier viele Beiträge zum DS1820 vorhanden sind, komme ich nicht 
zum Ergebnis.
Ich möchte nur einen einzigen Sensor abfragen und das Ergebnis auf ein 
Display bringen.
Hat jemand ein Beispiel für ein AVR5 Board in C ?

Mfg Robert

von Mike (Gast)


Lesenswert?

RobertP schrieb:
> obwohl hier viele Beiträge zum DS1820 vorhanden sind, komme ich nicht
> zum Ergebnis.

Woran hängt es denn und was hat du probiert. Zeig mal deinen Code und 
einen Link zu einer Beschreibung/Schaltplan von deinem Board.
Und wie hast du deine Sensoren angeschlossen?

von Tobias N. (silberkristall)


Lesenswert?

Hi, hier mal nen Code:

ow.h
1
/*** Devices ***/
2
unsigned char sensor1[8] = {16,157,172,77,2,8,0,86};
3
unsigned char sensor2[8] = {40,157,196,144,5,0,0,12};
4
/*** Devices ende ***/
5
6
unsigned char rom_c[8];
7
8
unsigned char ow_reset(void);
9
void write_bit(char bitval);
10
unsigned char read_bit(void);
11
unsigned char ow_rd_byte(void);
12
void ow_wr_byte(char val);
13
unsigned char ow_rd_rom(void);
14
unsigned char Read_Skip_Temp(void);
15
unsigned char Read_Match_Temp(unsigned char* romaddr);

ow.c
1
#include <util/delay.h>
2
#include <avr/io.h>
3
#include <timer.h>
4
5
#define    OWDDR    DDRA
6
#define    OWPIN    PINA
7
#define    OWPORT    PORTA
8
#define    OWICPIN    PA3
9
10
unsigned char rom_c[8];
11
12
unsigned char ow_reset(void)
13
{
14
    unsigned char zw;
15
  
16
    OWDDR |= (1<<OWICPIN);   // 1-wire Leitung auf LOW (Ausgang)
17
    OWPORT &= ~(1<<OWICPIN);                     // DQ auf Low
18
  
19
    _delay_us(460);                              // 460 us warten
20
  
21
    OWPORT |= (1<<OWICPIN);                      // DQ auf High
22
    OWDDR &= ~(1<<OWICPIN);       // 1-wire Leitung auf High (Eingang)
23
  
24
    _delay_us(65);                         // 65 us warten
25
  
26
    zw = (OWPIN & (1<<OWICPIN)) >> OWICPIN;                 // Zustand DQ einlesen
27
    _delay_us(420);                              // 420 us warten = Ende des Reset-Vorgangs
28
    return(zw);             // Rueckgabe: 0 = Slave vorhanden, 1 = kein Slave vorhanden
29
}
30
31
void ow_wr_bit(unsigned char bitwert)
32
{
33
    // Start Time Slot: DQ auf Low
34
  OWDDR |= (1<<OWICPIN);   // 1-wire Leitung auf LOW (Ausgang)
35
  OWPORT &= ~(1<<OWICPIN); // DQ auf Low
36
  
37
  // Bei logŽ1Ž: sofort wieder auf High = nur kurzer Low-Impuls
38
    if(bitwert)
39
  {
40
    OWPORT |= (1<<OWICPIN); // DQ auf High
41
  }
42
    
43
    _delay_us(105);                   // ca. 105 us warten bis
44
    
45
    OWPORT |= (1<<OWICPIN); // DQ auf High
46
}
47
48
unsigned char ow_rd_bit(void)
49
{
50
    unsigned char zw;
51
52
    OWDDR |= (1<<OWICPIN);   // 1-wire Leitung auf LOW (Ausgang)
53
    OWPORT &= ~(1<<OWICPIN); // DQ auf Low
54
    OWPORT |= (1<<OWICPIN); // DQ sofort wieder High
55
    OWDDR &= ~(1<<OWICPIN);       // 1-wire Leitung auf High (Eingang)
56
    _delay_us(15);         // 15 us warten
57
    zw = (OWPIN & (1<<OWICPIN)) >> OWICPIN;                   // DQ einlesen und speichern
58
    _delay_us(105);               // noch 105 us warten
59
                                // bis Ende Time Slot
60
    return(zw);                 // Rückgabe von DQ
61
}
62
63
void ow_wr_byte(unsigned char dat)
64
{
65
    unsigned char i;
66
    unsigned char maske = 1;
67
68
    // 8 Bits nacheinander raus schieben, LSB zuerst
69
    for (i=0; i<8; i++)
70
    {
71
        if (dat & maske) ow_wr_bit(1);          // log.Ž1Ž senden
72
        else ow_wr_bit(0);                      // log.Ž0Ž senden
73
        maske = maske * 2;                      // nächstes Bit selektieren
74
    }
75
}
76
77
unsigned char ow_rd_byte(void)
78
{
79
    unsigned char i;
80
    unsigned char wert = 0;
81
82
    // 8 Bits hintereinander einlesen, LSB zuerst
83
    for(i=0; i<8; i++)
84
    {
85
        if (ow_rd_bit()) wert |=0x01 << i;
86
    }
87
88
    return(wert);
89
}
90
91
unsigned char ow_rd_rom(void)
92
{
93
    unsigned char i;
94
95
    // Start mit Master-Reset-Impuls u. Abfrage: Slave presence
96
    if(ow_reset()) 
97
    {
98
        while(1);
99
    }
100
101
    // Abfrage-Befehl senden: "READ ROM" = 0x33
102
    ow_wr_byte(0x33);
103
104
    // Antwort einlesen: 8 Byte = 64 Bit Identifier ins globale Array rom_c[.]
105
    for (i=0; i<8; i++)
106
    {
107
        rom_c[i] = ow_rd_byte();
108
    }
109
  
110
  return rom_c[8];
111
}
112
113
114
115
// SkipRom
116
117
unsigned char Read_Skip_Temp(void)
118
{
119
    char get[10];
120
    int k;
121
    char temp_c;
122
      
123
    ow_reset();
124
    ow_wr_byte(0xCC); //Skip ROM
125
    ow_wr_byte(0x44); // Start Conversion
126
    _delay_ms(800);
127
    ow_reset();
128
    ow_wr_byte(0xCC); // Skip ROM
129
    ow_wr_byte(0xBE); // Read Scratch Pad
130
    for (k=0;k<9;k++){get[k]=ow_rd_byte();}
131
132
    temp_c = get[0]; // Temp data plus lsb
133
    temp_c = temp_c/2;
134
135
  return (temp_c);
136
}
137
138
// MatchRom
139
140
unsigned char Read_Match_Temp(unsigned char* romaddr)
141
{
142
    int get[10];
143
    int k;
144
    int i;
145
    int temp_c;
146
      
147
    ow_reset();
148
    ow_wr_byte(0x55);
149
    for (i=0; i<8; i++)
150
      {
151
        ow_wr_byte(romaddr[i]);
152
      }
153
154
    ow_wr_byte(0x44); // Start Conversion
155
    _delay_ms(800);
156
    ow_reset();
157
    
158
    ow_wr_byte(0x55);
159
    for (i=0; i<8; i++)
160
      {
161
        ow_wr_byte(romaddr[i]);
162
      }
163
    
164
    ow_wr_byte(0xBE); // Read Scratch Pad
165
    for (k=0;k<9;k++){get[k]=ow_rd_byte();}
166
    
167
    temp_c = get[0];
168
    temp_c = temp_c / 2;
169
170
  return (temp_c);
171
}

temperatur = Read_Skip_Temp(); und in temperatur steht dann deine 
Temperatur. Oben die defines musste noch anpassen.

Viel Spaß damit

von RobertP (Gast)


Lesenswert?

@ Tobias N.

Danke. Das sieht schon mal recht gut aus. Ich glaube das wird mir 
helfen.
Wie sieht denn die timer.h / .c aus ?

MFG

von RobertP (Gast)


Lesenswert?

Noch ein Problem :

Build started 31.3.2014 at 20:22:58
avr-gcc  -mmcu=atmega32 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT test.o -MF 
dep/test.o.d  -c  ../test.c
In file included from ../test.c:11:0:
../ow.c:63:6: error: conflicting types for 'ow_wr_byte'
../ow.h:14:6: note: previous declaration of 'ow_wr_byte' was here
make: *** [test.o] Fehler 1
Build failed with 1 errors and 0 warnings...

von Tobias N. (silberkristall)


Lesenswert?

Poste mal dein test.c code

von RobertP (Gast)


Lesenswert?

#define F_CPU 4000000

#include <avr/io.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "lcd.h"
#include "lcd.c"
#include "wdt.h"
#include "ow.h"
#include "ow.c"
#include <util/delay.h>



int main (){;

lcd_init(LCD_DISP_ON);
char buffer [10] ;


int test = 8;




lcd_gotoxy(0,0);
sprintf(buffer, "T = %d ", test);
lcd_puts(buffer);
lcd_puts("          ");



}

von RobertP (Gast)


Lesenswert?

Wie ich schon erwähnte hab ich diese timer.h /c nicht.

von Tobias N. (silberkristall)


Lesenswert?

ich hatte den Code bereits umgeändert. Daher ist da die timer.h drinne 
da ich das auslesen bereits per Timer nur nicht mehr mit delay mache 
damit der µC in der Zeit weiter arbeiten kann. Die Zeile kannst du 
eigentlich komplett da raus löschen, also die timer.h nicht includieren.

Und *.c files includiert man über das Makefile ;)

: Bearbeitet durch User
von RobertP (Gast)


Lesenswert?

Aha. Wie funktioniert denn das wohl bei AVR Studio 4.19 ?

von RobertP (Gast)


Lesenswert?

OK. Frage hat sich erledigt... wer lesen kann...

temperatur = Read_Skip_Temp();

welchen Datentyp muss ich hier für temperatur verwenden ?

von Tobias N. (silberkristall)


Lesenswert?

Kannst char oder unsigned char nehmen. Musst das aber dann noch 
umrechnen.
1
char temp_c;
2
char Buffer[20];
3
4
temp_c = Read_Skip_Temp();
5
6
sprintf(Buffer,"%+03d.%1d", temp_c/2, ( temp_c%2) * 5 );

: Bearbeitet durch User
von RobertP (Gast)


Lesenswert?

#define F_CPU 1000000UL

#include <avr/io.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "lcd.h"
#include "wdt.h"
#include "ow.h"
#include <util/delay.h>



int main (){;

lcd_init(LCD_DISP_ON);

char temp_c;
char buffer[20];

while (1){
temp_c = Read_Skip_Temp();

lcd_gotoxy(0,0);
sprintf(buffer,"%+03d.%1d", temp_c/2, ( temp_c%2) * 5 );
lcd_puts(buffer);
lcd_puts("          ");

}

}


Hmmm. Durgehend 63,5 °
Ist übrigens ein ATMEGA32.

von Tobias N. (silberkristall)


Lesenswert?

Also 127 wenn du das ganze ohne das sprintf machst. Dann, so war es 
zumindestens bei mir klappt der reset nicht. "könnte" am falschen Port 
liegen. Hast du die #defines angepasst? Port, Pin usw?

von RobertP (Gast)


Lesenswert?

Ich habs nochmal mit nem anderen Pin versucht. Gleiches Ergebnis.
Aber vielleicht das hier ? :

c:\program files (x86)\atmel\avr tools\avr 
toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h: 
89:3:  warning: #warning "F_CPU not defined for <util/delay.h>"
../ow.c: In function 'ow_rd_rom':
../ow.c:110:15: warning: array subscript is above array bounds

von RobertP (Gast)


Lesenswert?

Das mit dem F_CPU passt jetzt auch. Bleibt nur noch :

../ow.c: In function 'ow_rd_rom':
../ow.c:110:15: warning: array subscript is above array bounds

von RobertP (Gast)


Lesenswert?

OK....
Ich hab des Rätsels Lösung gefunden. Der Bestückungsdruck auf dem AVR 
Board ist "falsch" . Er passt jedenfalls nicht zu dem Dallas 1820. Somit 
war VCC und GND vertauscht. Mit so was hab ich im Leben nicht gerechnet.
Und deswegen tagelangen Ärger.... Jetzt bekomme ich plausible Werte, die 
sich auch ändern. Ob sie passen werde ich dann morgen nochmal melden. 
Ich hoffe er hat´s überlebt. Lt. Datenblatt sollte ihm das nichts 
ausmachen.

Ich sag nochmal Dankeschön.

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.