Atmega48_LED_Test.c


1
/*
2
Atmega verbunden mit einem DS18S20 Temperatursensor
3
8 LED's geben die gemessene Temperatur aus
4
Die LED's sind an PORTB
5
Beinchen | Wert in °C
6
---------------------
7
B0           1
8
B1       2
9
B2       4
10
B3       8
11
B4       10
12
B5       20
13
B6       40
14
B7       80
15
16
die Leuchtenden LED's werden einfach addiert und somit kann die Gesammttemperatur abgelesen werden
17
18
Am PORT D sind 8 Schalter angeschlossen deren Werte denen der LED's entsprechen, damit lässt sich die Solltemperatur
19
einstellen. Ist diese Erreicht bzw stimmt diese mit der am DS18S20 gemessenen Temperatur überein so wird ein Relais ausgeschaltet
20
21
Relais ist an C0
22
*/
23
#include <avr/io.h>
24
#include <avr/interrupt.h>
25
#define F_CPU 2000000
26
#include <util/delay.h>
27
#include <inttypes.h>
28
#include <stdint.h>
29
30
#define TRUE 1
31
#define FALSE 0
32
33
// Anchlussbelegung: An welchen Pins h?ngt der DS1820
34
#define W1_PIN  PC0                 //PB0 Pin soll der W1_PIN sein - in diesem Fall ist es der DataPin vom DS1820
35
#define W1_IN   PINC                //Pin abfragen
36
#define W1_OUT  PORTC               //Ausg?nge ansteuern
37
#define W1_DDR  DDRC                //Datenrichtung jeweils festlegen - je nach dem ob daten zum DS gesedent, oder vom DS empfangen werden sollen
38
#define LED_OUT PORTB
39
#define LED_DDR DDRB
40
#define RELAIS_C  PC1          //Relais an C1
41
42
// Kommandos an den DS1820
43
#define MATCH_ROM     0x55      //64 Bit code wird vom Master an ale DS gesendet - nur der DS mit dem Passenden 64Bit "namen" antwortet
44
#define SKIP_ROM      0xCC        //Master spricht alle DS simultan an - gefollgt von einem Convert_t beginnen alle mit der Temp. Konvertierung
45
#define SEARCH_ROM    0xF0        //identifizieren aller 64Bit adressen der angeschlosenen DS
46
#define CONVERT_T     0x44        //startet eine Temperaturkonvertierung und legt die daten im scratchpad (2byte gro?er Speicher im DS) ab
47
#define READ          0xBE        //scratchpad auslesen (Read Befehl an DS schicken)
48
#define WRITE         0x4E        //master beschreibt scratchpad (Write Befehl an den DS schicken)
49
#define EE_WRITE      0x48      //scratchpad daten in den EEPROM kopieren
50
#define EE_RECALL     0xB8      //
51
52
//Reset bei DS1820 ausl?sen (d.h. Master sendet min. 480?s low, dann high,
53
//nach 60...240?s sendet der DS1820 ein low zur?ck)
54
uint8_t w1_reset( void )
55
{
56
        uint8_t err;
57
58
        W1_OUT &= ~(1<<W1_PIN);                //C0 = W1-PIN als Ausgang mit einem low ansteuern
59
        W1_DDR |= 1<<W1_PIN;                   //W1_PIN als Ausgang alle anderen bleiben unangetastet
60
        _delay_us( 480 );                      //mindestens 480?s warten
61
        cli();                                 //das Global Interrupt Enable Bit im Status Register wird gel?scht
62
        W1_DDR &= ~(1<<W1_PIN);                //W1_PIN als Eingang
63
        _delay_us( 66 );                       //66?s warten
64
        err = W1_IN & (1<<W1_PIN);             //in err den Zustand von W1_IN speichern (im besten Fall ein low vom DS1820)
65
        sei();                                 //das Global Interrupt Enable Bit im Status Register wird gesetzt
66
        _delay_us( 480 - 66 );                 //warten
67
        if( (W1_IN & (1<<W1_PIN)) == 0 )       // Vergleich -> ist er genau 0 dann err=1
68
        err = 1;
69
        return err;                            //d.h. ist nun in err eine 1 so hat der DS1820 geantwortet
70
}
71
//schreibt ein Bit in den IC, gleichzeitig wird ein Bit vom DS empfangen
72
uint8_t w1_bit_io( uint8_t b )
73
74
{
75
        cli();                                 //das Global Interrupt Enable Bit im Status Register wird gel?scht
76
        W1_DDR |= 1<<W1_PIN;                   //W1_PIN als Ausgang
77
        _delay_us( 1 );                        //warten
78
        if( b )
79
        W1_DDR &= ~(1<<W1_PIN);                //falls W1_PIN als Eingang geschaltet
80
        _delay_us( 15 - 1 );                   //warten
81
        if( (W1_IN & (1<<W1_PIN)) == 0 )       //falls das logische & von ==0 ergibt
82
        b = 0;                                 //b=0
83
        _delay_us( 60 - 15 );                  //warten
84
        W1_DDR &= ~(1<<W1_PIN);                //W1_PIN als Eingang
85
        sei();                                 //das Global Interrupt Enable Bit im Status Register wird gesetzt
86
        return b;
87
}
88
89
90
//benutzt w1_bit_io um nacheinander 8 Bit zum IC zu schicken bzw. umgekehrt gleichzeitig 8 Bit vom IC zu holen
91
uint8_t w1_byte_wr( uint8_t b )
92
{
93
        uint8_t i = 8, j;                      //8Bit lang
94
95
        do {
96
            j = w1_bit_io( b & 1 );            //das Ergebniss aus w1_bit_io
97
            b >>= 1;
98
            if( j )
99
               b |= 0x80;                      //b oder= 0b10000000  
100
        } while( --i );
101
        return b;
102
}
103
//liest ein Byte vom DS1820
104
uint8_t w1_byte_rd( void )
105
{
106
        return w1_byte_wr( 0xFF );                
107
}
108
//?bertrag?t ein Kommando zu IC
109
void w1_command( uint8_t command )
110
{
111
        w1_reset();                             //zuerst die restet prozedur
112
        w1_byte_wr( SKIP_ROM );                 //dann alle DS1820 simultan ansprechen
113
        w1_byte_wr( command );                  //dann das Kommando
114
}
115
//Messung starten
116
uint8_t start_meas( void )
117
{
118
        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
119
           w1_command( CONVERT_T );            //(then)fals high ausgelesen wurde zum Konvertierungsschritt ?bergehen
120
           W1_OUT |= 1 << W1_PIN;              //(else) ein high zum ausgang senden
121
           return TRUE;
122
        }
123
        return FALSE;
124
}
125
126
//Temperatur vom DS abholen
127
int16_t read_meas_fast( void )
128
{
129
        uint16_t temp;
130
        w1_command( READ );                    // read command
131
        temp = w1_byte_rd();                   // low byte wird nach temp gespeichert
132
        temp |= (uint16_t)w1_byte_rd() << 8;   // high byte wird nach temp gespeichert
133
        //  if( id[0] == 0x10 )                // 9 -> 12 bit
134
        temp <<= 3;
135
        return temp;
136
}
137
138
139
int main(void)
140
{
141
    uint8_t t_soll = 0;          //Variable zum speichern der Zustände von D
142
    uint8_t t_ist =0; 
143
    int8_t xx;         
144
        const uint16_t pause = 200;
145
    const uint16_t pause_2 =80;
146
147
      int8_t p;
148
    int8_t tC;
149
        int16_t t;
150
    int16_t u;
151
    int8_t aa = 0b00010001; 
152
    int8_t bb = 0b00110011;
153
    int8_t cc = 0b01110111;
154
    int8_t dd = 0b11111111;
155
    int8_t ee = 0b11101110;
156
    int8_t ff = 0b11001100;
157
    int8_t gg = 0b10001000;
158
    int8_t hh = 0b10000001;
159
    int8_t ii = 0b11000011;
160
    int8_t jj = 0b11100111;
161
    int8_t kk = 0b11111111;
162
    int8_t ll = 0b01111110;
163
    int8_t mm = 0b00111100;
164
    int8_t nn = 0b00011000;
165
    int8_t oo = 0b10001000;
166
    int8_t pp = 0b10000001;
167
    int8_t qq = 0b11000011;
168
    int8_t rr = 0b11100111;
169
    int8_t ss = 0b11111111;
170
    int8_t tt = 0b01111110;
171
    int8_t uu = 0b00111100;
172
    int8_t vv = 0b00011000;
173
    
174
    DDRD = 0x00;                            //D als Input
175
    DDRC = 0xff;                  //C als Output
176
    PORTC = 0x00;                     //fangen alle bei 0V an
177
        DDRB = 0xff;                                    //alle B Port Pins sind Output
178
        PORTB = 0x00;                     //fangen alle bei 0V an
179
        // Initialisierung als Lauflicht
180
        for(int a=0; a<2; a++)
181
        {
182
                PORTB = ~aa; 
183
                _delay_ms(pause);
184
                PORTB = ~bb;
185
                _delay_ms(pause);
186
                PORTB = ~cc;
187
                _delay_ms(pause);
188
                PORTB = ~dd;
189
                _delay_ms(pause);
190
                PORTB = ~ee;
191
                _delay_ms(pause);
192
                PORTB = ~ff;
193
                _delay_ms(pause);
194
                PORTB = ~gg;
195
                _delay_ms(pause);
196
                PORTB = ~ff;
197
                _delay_ms(pause);
198
                PORTB = ~ee;
199
                _delay_ms(pause);
200
                PORTB = ~dd;
201
                _delay_ms(pause);
202
                PORTB = ~cc;
203
                _delay_ms(pause);
204
                PORTB = ~bb;
205
                _delay_ms(pause);
206
                PORTB = ~aa;
207
        }
208
209
        for(int a=0; a<2; a++){
210
                PORTB = ~hh;
211
                _delay_ms(pause);
212
                PORTB = ~ii;
213
                _delay_ms(pause);
214
        PORTB = ~jj;
215
                _delay_ms(pause);
216
                PORTB = ~kk;
217
                _delay_ms(pause);
218
        PORTB = ~ll;
219
                _delay_ms(pause);
220
                PORTB = ~mm;
221
                _delay_ms(pause);
222
        PORTB = ~nn;
223
                _delay_ms(pause);
224
                PORTB = ~mm;
225
                _delay_ms(pause);
226
          PORTB = ~ll;
227
                _delay_ms(pause);
228
                PORTB = ~kk;
229
                _delay_ms(pause);
230
        PORTB = ~jj;
231
                _delay_ms(pause);
232
                PORTB = ~ii;
233
                _delay_ms(pause);
234
        PORTB = ~hh;
235
                _delay_ms(pause);
236
        }
237
238
    for(int a=0; a<10; a++){
239
                PORTB = ~oo;
240
                _delay_ms(pause_2);
241
                PORTB = ~pp;
242
                _delay_ms(pause_2);
243
                PORTB = ~qq;
244
                _delay_ms(pause_2);
245
                PORTB = ~rr;
246
                _delay_ms(pause_2);
247
                PORTB = ~ss;
248
                _delay_ms(pause_2);
249
        PORTB = ~tt;
250
                _delay_ms(pause_2);
251
        PORTB = ~uu;
252
                _delay_ms(pause_2);
253
          PORTB = ~vv;
254
                _delay_ms(pause_2);
255
    }
256
    
257
258
259
        // Port x, alle Pins als Ausgang schalten (Grundeinstellung)
260
      W1_DDR = 0xFF;
261
        // Port x, Pins initialisieren (low)
262
        W1_OUT = 0x00;
263
        // Sensor initialisieren
264
        // >>Notiz>> Wir gehen einfach von einem Erfolg aus <<
265
        w1_reset();
266
        // Hauptschleife
267
        do
268
        {
269
270
                // Kommando an den Sensor (Messung starten)
271
                // >>Notiz>> Wir gehen einfach von einem Erfolg aus <<
272
                start_meas();
273
        
274
                // Temperatur vom Sensor holen
275
                t = read_meas_fast();
276
        t = t/8;
277
        u = t;
278
279
                // Temperatur in Grad Celsius:
280
                tC = (t >> 1) | (t & 0xFF00);
281
        
282
                if(tC < 0) tC = -tC; //Vorzeichen entfernen
283
                        
284
285
                //reset (alle LEDs aus)
286
                p = 0x00;
287
288
           //Konfiguration der Pins für LEDs setzen
289
                // (0 = LED an, 1 = LED aus)
290
                if(tC >= 80) { p |=(1<<7); tC -= 80; } //Pin7 f?r 80?C an
291
                if(tC >= 40) { p |=(1<<6); tC -= 40; } //Pin6 f?r 40?C an
292
                if(tC >= 20) { p |=(1<<5); tC -= 20; } //Pin5 f?r 20?C an
293
                if(tC >= 10) { p |=(1<<4); tC -= 10; } //Pin4 f?r 10?C an
294
                if(tC >= 8)  { p |=(1<<3); tC -= 8;  } //Pin3 f?r 8?C  an
295
                if(tC >= 4)  { p |=(1<<2); tC -= 4;  } //Pin2 f?r 4?C  an
296
                if(tC >= 2)  { p |=(1<<1); tC -= 2;  } //Pin1 f?r 2?C  an
297
                if(tC >= 1)  { p |=(1<<0); tC -= 1;  } //Pin0 f?r 1?C  an
298
299
           t_ist = p;
300
        //Solltemp. in der Schleife abholen ermöglicht Solltemp nachzuregeln
301
        t_soll = PIND;        //Status von D in SchalterD speichern
302
303
304
        p = ~p;            //LED Signal invertieren weil LED falsch angelötet
305
        //p = p-0,5;        //Eichung des Thermometers
306
        LED_OUT = p;
307
308
    
309
      
310
        ///Hysterese...Relais
311
        ///t_ist/    kommt vom Temp. - sensor
312
        ///t_soll/  kommt von PIND
313
314
        if((t_ist <= t_soll - 1)) //&& !(PORTC & (1<<RELAIS_C)))
315
        {
316
         //Heizung //an //(Relais HIGH)
317
         PORTC |= (1<<RELAIS_C);
318
        }
319
        else if((t_ist >= t_soll + 1))// && (PORTC & (1<<RELAIS_C)))
320
        {
321
         //Heizung////aus //(Relais LOW)//
322
         PORTC &= ~ (1<<RELAIS_C);
323
        }
324
325
326
        // ein wenig warten verhindert,
327
                // dass der Sensor durch Selbsterw?rmung
328
                // falsche Ergebnisse liefert
329
                _delay_ms(1000);
330
331
         
332
333
334
335
        }while(1);
336
337
}