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
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?
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
@ 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
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...
#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(" "); }
Wie ich schon erwähnte hab ich diese timer.h /c nicht.
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
OK. Frage hat sich erledigt... wer lesen kann... temperatur = Read_Skip_Temp(); welchen Datentyp muss ich hier für temperatur verwenden ?
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
#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.
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?
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.