1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #define F_CPU 8000000 //-> bereits unter Project->Configuration Options-> als 8000000 definiert
|
4 | #include <util/delay.h>
|
5 | #include <inttypes.h>
|
6 | #include <stdint.h>
|
7 |
|
8 | #define TRUE 1
|
9 | #define FALSE 0
|
10 |
|
11 | // Anchlussbelegung: An welchen Pins h?ngt der DS1820 bzw die LED Anzeige
|
12 | #define W1_PIN PC0 //PC0 Pin soll der W1_PIN sein - in diesem Fall ist es der DataPin vom DS1820
|
13 | #define W2_PIN PC1 //PC0 Pin soll der W1_PIN sein - in diesem Fall ist es der DataPin vom DS1820
|
14 | #define W1_IN PINC //Pin abfragen
|
15 | #define W1_OUT PORTC //Ausg?nge ansteuern
|
16 | #define W1_DDR DDRC //Datenrichtung jeweils festlegen - je nach dem ob Daten zum DS gesedent, oder vom DS empfangen werden sollen
|
17 | #define LED_OUTB PORTB //PORT für die LED Anzeige
|
18 | #define LED_DDRB DDRB //DDR für die LED Anzeige
|
19 | #define LED_OUTA PORTA //PORT für die LED Anzeige
|
20 | #define LED_DDRA DDRA //DDR für die LED Anzeige
|
21 | #define LED_OUTD PORTD //PORT für die LED Anzeige
|
22 | #define LED_DDRD DDRD //DDR für die LED Anzeige
|
23 |
|
24 | // Kommandos an den DS1820
|
25 | #define MATCH_ROM 0x55 //64 Bit code wird vom Master an ale DS gesendet - nur der DS mit dem Passenden 64Bit "namen" antwortet
|
26 | #define SKIP_ROM 0xCC //Master spricht alle DS simultan an - gefollgt von einem Convert_t beginnen alle mit der Temp. Konvertierung
|
27 | #define SEARCH_ROM 0xF0 //identifizieren aller 64Bit adressen der angeschlosenen DS
|
28 | #define CONVERT_T 0x44 //startet eine Temperaturkonvertierung und legt die daten im scratchpad (2byte gro?er Speicher im DS) ab
|
29 | #define READ 0xBE //scratchpad auslesen (Read Befehl an DS schicken)
|
30 | #define WRITE 0x4E //master beschreibt scratchpad (Write Befehl an den DS schicken)
|
31 | #define EE_WRITE 0x48 //scratchpad daten in den EEPROM kopieren
|
32 | #define EE_RECALL 0xB8 //
|
33 |
|
34 | //Reset bei DS1820 ausl?sen (d.h. Master sendet min. 480?s low, dann high,
|
35 | //nach 60...240?s sendet der DS1820 ein low zur?ck)
|
36 | uint8_t w1_reset( void )
|
37 | {
|
38 | uint8_t err;
|
39 |
|
40 | W1_OUT &= ~(1<<W1_PIN); //C0 = W1-PIN als Ausgang mit einem low ansteuern
|
41 | W1_DDR |= 1<<W1_PIN; //W1_PIN als Ausgang alle anderen bleiben unangetastet
|
42 | _delay_us( 480 ); //mindestens 480?s warten
|
43 | cli(); //das Global Interrupt Enable Bit im Status Register wird gel?scht
|
44 | W1_DDR &= ~(1<<W1_PIN); //W1_PIN als Eingang
|
45 | _delay_us( 66 ); //66?s warten
|
46 | err = W1_IN & (1<<W1_PIN); //in err den Zustand von W1_IN speichern (im besten Fall ein low vom DS1820)
|
47 | sei(); //das Global Interrupt Enable Bit im Status Register wird gesetzt
|
48 | _delay_us( 480 - 66 ); //warten
|
49 | if( (W1_IN & (1<<W1_PIN)) == 0 ) // Vergleich -> ist er genau 0 dann err=1
|
50 | err = 1;
|
51 | return err; //d.h. ist nun in err eine 1 so hat der DS1820 geantwortet
|
52 | }
|
53 |
|
54 | //schreibt ein Bit in den IC, gleichzeitig wird ein Bit vom DS empfangen
|
55 | uint8_t w1_bit_io( uint8_t b )
|
56 | {
|
57 | cli(); //das Global Interrupt Enable Bit im Status Register wird gel?scht
|
58 | W1_DDR |= 1<<W1_PIN; //W1_PIN als Ausgang
|
59 | _delay_us( 1 ); //warten
|
60 | if( b )
|
61 | W1_DDR &= ~(1<<W1_PIN); //falls W1_PIN als Eingang geschaltet
|
62 | _delay_us( 15 - 1 ); //warten
|
63 | if( (W1_IN & (1<<W1_PIN)) == 0 ) //falls das logische & von ==0 ergibt
|
64 | b = 0; //b=0
|
65 | _delay_us( 60 - 15 ); //warten
|
66 | W1_DDR &= ~(1<<W1_PIN); //W1_PIN als Eingang
|
67 | sei(); //das Global Interrupt Enable Bit im Status Register wird gesetzt
|
68 | return b;
|
69 | }
|
70 |
|
71 | //benutzt w1_bit_io um nacheinander 8 Bit zum IC zu schicken bzw. umgekehrt gleichzeitig 8 Bit vom IC zu holen
|
72 | uint8_t w1_byte_wr( uint8_t b )
|
73 | {
|
74 | uint8_t i = 8, j; //8Bit lang
|
75 |
|
76 | do {
|
77 | j = w1_bit_io( b & 1 ); //das Ergebniss aus w1_bit_io
|
78 | b >>= 1;
|
79 | if( j )
|
80 | b |= 0x80; //b oder= 0b10000000
|
81 | } while( --i );
|
82 | return b;
|
83 | }
|
84 |
|
85 | //liest ein Byte vom DS1820
|
86 | uint8_t w1_byte_rd( void )
|
87 | {
|
88 | return w1_byte_wr( 0xFF );
|
89 | }
|
90 |
|
91 | //?bertrag?t ein Kommando zu IC
|
92 | void w1_command( uint8_t command )
|
93 | {
|
94 | w1_reset(); //zuerst die restet prozedur
|
95 | w1_byte_wr( SKIP_ROM ); //dann alle DS1820 simultan ansprechen
|
96 | w1_byte_wr( command ); //dann das Kommando
|
97 | }
|
98 |
|
99 | //Messung starten
|
100 | uint8_t start_meas( void )
|
101 | {
|
102 | if( W1_IN & ( 1 << W1_PIN ) ) { //kleine Fehlererkennung - pr?ft ob der Pegel high ist (Ist der Pin daher auf Eingang geschaltet, dann muss es n?glich sein, beiinaktivem Bus einen HighPegel auszulesen) wird ein high gelesen ist alles True sonst False
|
103 | w1_command( CONVERT_T ); //(then)fals high ausgelesen wurde zum Konvertierungsschritt ?bergehen
|
104 | W1_OUT |= 1 << W1_PIN; //(else) ein high zum ausgang senden
|
105 | return TRUE;
|
106 | }
|
107 | return FALSE;
|
108 | }
|
109 |
|
110 | //Temperatur vom DS abholen
|
111 | int16_t read_meas_fast( void )
|
112 | {
|
113 | uint16_t temp;
|
114 | w1_command( READ ); // read command
|
115 | temp = w1_byte_rd(); // low byte wird nach temp gespeichert
|
116 | temp |= (uint16_t)w1_byte_rd() << 8; // high byte wird nach temp gespeichert
|
117 | // if( id[0] == 0x10 ) // 9 -> 12 bit
|
118 | temp <<= 3;
|
119 | return temp;
|
120 | }
|
121 |
|
122 | int main(void)
|
123 | {
|
124 | const uint16_t pause = 1000;
|
125 |
|
126 | int8_t p;
|
127 | int8_t tC;
|
128 | int16_t t;
|
129 | int8_t pp;
|
130 | int8_t ttC;
|
131 | int16_t tt;
|
132 | uint8_t t_ist =0;
|
133 | uint8_t tt_ist =0;
|
134 | int8_t aa = 0b00000000;
|
135 | int8_t bb = 0b11111111;
|
136 |
|
137 | DDRC = 0xff; //C als Output
|
138 | PORTC = 0x00; //fangen alle bei 0V an
|
139 | DDRA = 0xff; //alle A Port Pins sind Output
|
140 | PORTA = 0x00; //fangen alle bei 0V an
|
141 | DDRB = 0xff; //alle B Port Pins sind Output
|
142 | PORTB = 0x00; //fangen alle bei 0V an
|
143 | DDRD = 0xff; //alle D Port Pins sind Output
|
144 | PORTD = 0x00; //fangen alle bei 0V an
|
145 |
|
146 | // Initialisierung der LED (Prüfen ob alle leuchten)
|
147 | for(int a=0; a<10; a++)
|
148 | {
|
149 | PORTA = aa;
|
150 | PORTB = ~aa;
|
151 | PORTD = ~aa;
|
152 | for(int a=0; a<1; a++){ _delay_ms(pause);}
|
153 | PORTA = bb;
|
154 | PORTB = ~aa;
|
155 | PORTD = ~aa;
|
156 | for(int b=0; b<1; b++){ _delay_ms(pause);}
|
157 | }
|
158 |
|
159 |
|
160 |
|
161 | // Port x, alle Pins als Ausgang schalten (Grundeinstellung)
|
162 | W1_DDR = 0xFF;
|
163 | // Port x, Pins initialisieren (low)
|
164 | W1_OUT = 0x00;
|
165 | // Sensor initialisieren
|
166 | // >>Notiz>> Wir gehen einfach von einem Erfolg aus <<
|
167 | w1_reset();
|
168 | // Hauptschleife
|
169 | do
|
170 | {
|
171 |
|
172 | // Kommando an den Sensor (Messung starten)
|
173 | // >>Notiz>> Wir gehen einfach von einem Erfolg aus <<
|
174 | start_meas();
|
175 |
|
176 | // Temperatur vom Sensor holen
|
177 | t = read_meas_fast();
|
178 | t = t/8;
|
179 |
|
180 | // Temperatur in Grad Celsius:
|
181 | tC = (t >> 1) | (t & 0xFF00);
|
182 |
|
183 | if(tC < 0) tC = -tC; //Vorzeichen entfernen
|
184 |
|
185 | //reset (alle LEDs aus)
|
186 | p = 0x00;
|
187 |
|
188 | //Konfiguration der Pins für LEDs setzen
|
189 | // (0 = LED an, 1 = LED aus)
|
190 | if(tC >= 80) { p |=(1<<7); tC -= 80; } //Pin7 f?r 80?C an
|
191 | if(tC >= 40) { p |=(1<<6); tC -= 40; } //Pin6 f?r 40?C an
|
192 | if(tC >= 20) { p |=(1<<5); tC -= 20; } //Pin5 f?r 20?C an
|
193 | if(tC >= 10) { p |=(1<<4); tC -= 10; } //Pin4 f?r 10?C an
|
194 | if(tC >= 8) { p |=(1<<3); tC -= 8; } //Pin3 f?r 8?C an
|
195 | if(tC >= 4) { p |=(1<<2); tC -= 4; } //Pin2 f?r 4?C an
|
196 | if(tC >= 2) { p |=(1<<1); tC -= 2; } //Pin1 f?r 2?C an
|
197 | if(tC >= 1) { p |=(1<<0); tC -= 1; } //Pin0 f?r 1?C an
|
198 |
|
199 | t_ist = p;
|
200 | //p = p-0,5; //Eichung des Thermometers
|
201 |
|
202 | LED_OUTA = p;
|
203 | LED_OUTD = p;
|
204 | p = ~p; //LED Signal invertieren weil LED falsch angelötet
|
205 | LED_OUTB = p;
|
206 |
|
207 | // ein wenig warten verhindert,
|
208 | // dass der Sensor durch Selbsterw?rmung
|
209 | // falsche Ergebnisse liefert
|
210 | _delay_ms(1000);
|
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 | }while(1);
|
217 |
|
218 | }
|