loet.c


1
/* 
2
;
3
Lötstation für Weller LR21
4
5
Funktion:
6
der SIGNAL (TIMER1_OVF_vect) Timerinterrupt (jede Sekunde)
7
misst die Thermospannung des Kolben über leseAD() und rechnet
8
diese in °C um.
9
Die Heizung wir eingeschaltet.
10
Je nach Regelabweichung wird die Heizung nach einer bestimmten 
11
Anzahl Nulldurchgänge der Netzspannung wieder ausgeschaltet.
12
Der Analogkomperator erkennt den Nulldurchgang und löst Interrupt 
13
(ANA_COMP_vect) aus.
14
Dort erfolgt auch ein und ausschalten jeweils im Nulldurchgang.
15
Der Stellwert kann 0 bis 50 Perioden in einer Sekunde betragen.
16
17
; Hardware
18
;              ___________
19
;       __    /           |      
20
;+5V O-|__|--|RESET    PC5|--O PWM-AUS - GND
21
;            |            |      
22
;         O--|PD0      PC4|--O LED - GND
23
;            |            |      
24
;         O--|PD1      PC3|--O Schalter am Ständer - GND
25
;            |            |     
26
;     LCD O--|PD2      PC2|--O Taster UP   - GND
27
;            |            |
28
;     LCD O--|PD3     ADC1|--O Taster Down - GND
29
;            |    A T     |
30
;     LCD O--|PD4     ADC0|--O AD-IN
31
;            |   mega     |
32
;     +5V O--|VCC      GND|--O GND
33
;            |     8      |    
34
;     GND O--|GND     AREF|--O
35
;            |            |      
36
;   XTAL1 O--|XTAL1   AVCC|--O
37
;            |            |
38
;   XTAL2 O--|XTAL2 PB5SCK|--O 
39
;            |            |
40
;         O--|PD5  PB4MISO|--O 
41
;            |            |
42
;         O--|PD6  PB3MOSI|--O LCD 
43
;            |            |
44
;         O--|PD7  PB2OC1B|--O LCD
45
;            |            |
46
;     LCD O--|PB0  PB1OC1A|--O LCD
47
;            |____________|
48
; 
49
*/
50
#include <avr/io.h>
51
#include <avr/interrupt.h>
52
#include <stdlib.h>
53
#include <stdint.h>
54
#include <Stdio.h>
55
#include <avr/eeprom.h>
56
#include "BinaryNr.h"
57
#include "lcd.h"
58
59
60
#define F_CPU            1000000    // Interner Takt 1MHz
61
#define Prescaler 1024;             // Timer 1 Vorteiler
62
#define startwert 65537-F_CPU/Prescaler; //Zähler Startwert, Überlauf bei 65536
63
64
#define u8 unsigned char
65
#define u16 unsigned int
66
67
/* Variablen */
68
char s[4];                          // Hilfsvariable  
69
u16 adWert;                         // AD-Wert 
70
u16 Tist;                           // IstTemperatur 
71
u16 Tsoll;                          // Solltemperatur 
72
u16 eeFooWord EEMEM = 280;          // EEprom Speicher
73
74
// ##############  A C H T U N G   ######################
75
// hier an den Temperaturfühler anpassen
76
// bei Platin- oder PTC-Fühler ausserdem RPTC1 und RPTC2(Brücke) einlöten
77
//***** edit ***** diese beiden Zeilen für Thermoelementfühler
78
//float faktor = 0.5889;            // Spannung in Temp. bei Thermoelement
79
//float n = 20;                     // y = mx + n bei Thermoelement 
80
//***** edit ***** diese beiden Zeilen für Platin- oder PTC-Fühler
81
float faktor = 0.73;                // Spannung in Temp. bei PTC
82
float n = -289;                     // y = mx + n bei PTC
83
84
u8 perioden=0;                      // zählt die Anzahl der Perioden (20ms)
85
u8 stellwert=0;                     // Einschaltdauer von 0 bis 50 (50 Perioden)
86
87
/* INIT */
88
void port_init(void){               // initialize ports 
89
  DDRC  = B00110000;                // PORTC 4 und 5 als Ausgang
90
  PORTC = B00001110;                // PullUps für Taster einschalten
91
}
92
93
void ad_init(void){                 // initialize ad-wandler 
94
  ADMUX = 0x00;                     // Kanal0
95
  ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung 2,5V nutzen 
96
  ADCSR=B11000111;                  // enable ADC
97
}
98
99
void ac_init(void){                 // initialize analog-Komparator 
100
  ACSR=B00001010;                   // enable ADC
101
}
102
103
void timer_init(void){              // timer 1 overflow 
104
  TCCR1B = B00000101;               // Prescaler auf 1024 stellen
105
  TIMSK |= (1 << TOIE1);            // Timer 1 Overflow Interrupt enable
106
  TCNT1  = startwert;               // vorbesetzen (zählt bis FFFF)
107
}
108
109
/* Unterprogramme */
110
111
//lies den Temperatur-Startwert aus EEPROM
112
int Lese_Starttemp(void){
113
  u16 startTemp;
114
  startTemp = eeprom_read_word(&eeFooWord); // lese aus EEPROM in startTemp
115
  if (startTemp==0){
116
    startTemp=280;
117
  }   
118
  return startTemp; 
119
}
120
121
//schreibe den Temperatur-Tsoll ins EEPROM
122
void Schreibe_Startemp(u16 wert){
123
   eeprom_write_word(&eeFooWord, wert); // schreibe in EEPROM
124
}
125
126
//lese ad0
127
int leseAD(void){
128
  uint16_t wert;                    // Hilfsvariable
129
  uint8_t  highwert;                // Hilfsvariable
130
  ADCSR |= (1<<ADSC);               // eine Wandlung starten
131
  while ( ADCSR & (1<<ADSC) ) {;}   // auf Abschluss der Konvertierung warten
132
  wert     = ADCL;                  // Low  auslesen  
133
  highwert = ADCH;                  // High auslesen
134
  wert = wert + highwert*256;       // 10bit Wert berechnen
135
  return wert;
136
}
137
138
//Anzeige der Isttemperatur auf LCD
139
void zeige_Tist(u16 temp){
140
  itoa(temp,s,10);                  // wert in ACSII
141
  lcd_gotoxy(0,0);                  // 1. Zeile   
142
  lcd_puts("aktuell  ");            // Zeichen auf LCD
143
  lcd_puts(s);                      // Temperatur als ASCII Wert auf LCD
144
  lcd_puts("\xDF" "C");             // Grad Zeichen                
145
}
146
147
//Anzeige der Solltemperatur auf LCD
148
void zeige_Tsoll(u16 temp){
149
  itoa(temp,s,10);                  // wert in ACSII
150
  lcd_gotoxy(0,1);                  // 2. Zeile   
151
  lcd_puts("Solltemp.   ");         // Zeichen auf LCD
152
  lcd_puts(s);                      // Temperatur als ASCII Wert auf LCD
153
  lcd_puts("\xDF" "C");             // Grad Zeichen                
154
}
155
156
157
void Pause(void){                   //etwa 0,1s        // nur zu Testzwecken 
158
  uint8_t i;
159
  uint8_t j;
160
  for(i=0;i<6;i++){
161
    for(j=0;j<250;j++) {}
162
  }
163
}
164
165
//Analog-Comparator Interrupt Routine je Netzspannungshalbwelle in Nulldurchgang
166
SIGNAL (ANA_COMP_vect){
167
168
  if (perioden==0){                 // Neuer Periodenzyclus hat begonnen
169
    PORTC |= (1 << 5);              // Heizung einschalten 
170
    PORTC |= (1 << 4);              // LED einschalten ***test*************
171
  }
172
  if (perioden==stellwert){         // Einschaltdauer (Periodenzahl) erreicht
173
      PORTC &= ~(1 << 5);           // Heizung abschalten
174
    PORTC &= ~(1 << 4);             // LED abschalten   ****test*********
175
    }
176
  perioden++;                       // wieder eine Periode vergangen
177
}
178
179
180
//Timer Interrupt - kommt genau jede Sekunde
181
SIGNAL (TIMER1_OVF_vect){           // Timer1 overflow 
182
  cli();                            // Alle Int. sperren solange in INT-Routine
183
  TCNT1 = startwert;                // Vorbesetzen (1s)
184
  perioden=0;                       // neuer Periodenzyclus
185
  lcd_clrscr();                     // 1.Zeile
186
  adWert=leseAD();                  // lese Spannungswert 
187
  Tist = adWert*faktor+n;           // Temperatur berechnen
188
  zeige_Tist(Tist);                 // anzeigen 
189
  if(bit_is_clear (PINC,1))         // wenn Taste DOWN gedrückt
190
  {
191
    if(Tsoll>10)                    // und min-wert noch nicht erreicht
192
    {
193
      Tsoll=Tsoll-10;               // erniedrige Tsoll
194
    Schreibe_Startemp(Tsoll);       // sichere Tsoll im EEPROM
195
    }
196
  }
197
  if(bit_is_clear (PINC,2))         // wenn Taste UP gedrückt
198
  {
199
    if(Tsoll<450)                   // und max-wert noch nicht erreicht  
200
    {
201
    Tsoll=Tsoll+10;                 // erhöhe Tsoll
202
    Schreibe_Startemp(Tsoll);       // sichere Tsoll im EEPROM
203
    }
204
  }     
205
  zeige_Tsoll(Tsoll);               // Solltemp. anzeigen 
206
207
// regelung ********************************************
208
  if (Tsoll<=Tist){                 // zu heiss 
209
    if (Tist-Tsoll < 10){           // weniger als 10 Grad Abweichung 
210
     stellwert = 20;                // Heizleistung 40%
211
    }
212
  else {                            // Abweichung größer 20 Grad C
213
      stellwert = 0;                // erst mal gar nicht Heizen
214
    }
215
  }
216
  if (Tsoll>Tist){                  // zu kalt
217
    if (Tsoll-Tist < 10){           // weniger als 10 Grad Abweichung 
218
     stellwert = 20;                // Heizleistung 40%
219
    }
220
  else {                            // Abweichung größer 20 Grad C
221
      stellwert = 50;               // 100% Heizleistung
222
    }
223
  }
224
225
  sei();                            // enable interrupts
226
}
227
/*********************/
228
int main(){
229
  port_init();                      // Ports initialisieren
230
  lcd_init(LCD_DISP_ON);            // initialisiere display, cursor off 
231
  ad_init();                        // AD-Wandler initialisieren
232
  ac_init();                        // initialisiere analog-Komparator
233
  timer_init();                     // Timer initialisieren
234
  Tsoll=Lese_Starttemp();           // Starttemperatur lesen, Vorgabe vom letzten mal 
235
  Schreibe_Startemp(Tsoll);         // Starttemperatur schreiben    
236
  lcd_puts("Start... ");            // Startmeldung auf LCD
237
  sei();                            // enable interrupts  
238
239
  for(;;){                          // tue nix Schleife
240
241
  }
242
}