komfortstart.c


1
// *********************
2
// Allgemeines Geplänkel
3
// *********************
4
#include <avr/io.h> // Grundfunktionen
5
#define F_CPU 1000000UL // CPU Frequenz
6
#include <util/delay.h> // Warteschleifen
7
8
9
10
// ***************************
11
// Globale Variablen festlegen
12
// ***************************
13
volatile uint8_t durchlauf = 0; // Programmdurchlauf erst wieder möglich, wenn alle Taster losgelassen sind
14
15
16
17
// *********************************
18
// FUNKTION: Zündung ein/ausschalten
19
// *********************************
20
int zuendung(int n)
21
{  
22
  if(n == 0) 
23
  {
24
    PORTC &= ~(1<<PC0); // Zündung ausschalten, Übergabewert aus = 0
25
  }
26
27
  if(n == 1) 
28
  {
29
    PORTC |= (1<<PC0); // Zündung einschalten, Übergabewert ein = 1
30
  }
31
  
32
  return 0;
33
}
34
35
36
37
// *********************************
38
// FUNKTION: Status Zündung abfragen
39
// *********************************
40
int status_zuendung(void)
41
{
42
  uint16_t warten = 1; // Anzahl Schleifendurchläufe * ms = Gesamtdauer
43
 
44
  while( (PINC & (1<<PINC0)) && (warten != 0) ) // Solange Eingangssignal erkannt und Zeit nicht abgelaufen
45
  {
46
    _delay_ms(25);
47
    warten--;
48
  }
49
50
  // Signal immer noch vorhanden UND Zeit abgelaufen? (sonst fehlen 25ms)
51
  if ( (PINC & (1<<PINC0)) && (warten == 0) )
52
    return 1;
53
  else
54
    return 0;
55
}
56
57
58
59
60
61
// *************************************************
62
// FUNKTION: Taster-Zustand auf GESCHLOSSEN abfragen
63
// *************************************************
64
int status_standardtaster(void)
65
{
66
  uint16_t warten = 1; // Anzahl Schleifendurchläufe * ms = Gesamtdauer
67
 
68
  while( (PIND & (1<<PIND5)) && (warten != 0) ) // Solange Eingangssignal erkannt und Zeit nicht abgelaufen
69
  {
70
    _delay_ms(25);
71
    warten--;
72
  }
73
74
  // Signal immer noch vorhanden UND Zeit abgelaufen? (sonst fehlen 25ms)
75
  if ( (PIND & (1<<PIND5)) && (warten == 0) )
76
    return 1;
77
  else
78
    return 0;
79
}
80
81
82
83
// *******************************************
84
// FUNKTION: Taster-Zustand auf OFFEN abfragen
85
// *******************************************
86
int status_standardtaster_offen(void)
87
{
88
  uint16_t warten = 1; // Anzahl Schleifendurchläufe * ms = Gesamtdauer
89
 
90
  while( !(PIND & (1<<PIND5)) && (warten != 0) ) // Solange Eingangssignal erkannt und Zeit nicht abgelaufen
91
  {
92
    _delay_ms(25);
93
    warten--;
94
  }
95
96
  // Signal immer noch vorhanden UND Zeit abgelaufen? (sonst fehlen 25ms)
97
  if ( !(PIND & (1<<PIND5)) && (warten == 0) )
98
    return 1;
99
  else
100
    return 0;
101
}
102
103
104
// *******************************
105
// FUNKTION: LiMa-Zustand abfragen
106
// *******************************
107
int status_lima(void)
108
{
109
  uint16_t warten = 2; // Anzahl Schleifendurchläufe * ms = Gesamtdauer
110
 
111
  while( (PIND & (1<<PIND0)) && (warten != 0) ) // Solange Eingangssignal erkannt und Zeit nicht abgelaufen
112
  {
113
    _delay_ms(25);
114
    warten--;
115
  }
116
117
  // Signal immer noch vorhanden UND Zeit abgelaufen? (sonst fehlen 25ms)
118
  if ( (PIND & (1<<PIND0)) && (warten == 0) )
119
    return 1;
120
  else
121
    return 0;
122
}
123
124
125
126
// *******************************
127
// FUNKTION: Pedalzustand abfragen
128
// *******************************
129
int status_pedal(void)
130
{
131
  uint16_t warten = 1; // Anzahl Schleifendurchläufe * ms = Gesamtdauer
132
 
133
  while( (PIND & (1<<PIND1)) && (warten != 0) ) // Solange Eingangssignal erkannt und Zeit nicht abgelaufen
134
  {
135
    _delay_ms(25);
136
    warten--;
137
  }
138
139
  // Signal immer noch vorhanden UND Zeit abgelaufen? (sonst fehlen 25ms)
140
  if ( (PIND & (1<<PIND1)) && (warten == 0) )
141
    return 1;
142
  else
143
    return 0;
144
}
145
146
147
148
// **********************************************
149
// FUNKTION: Zündschloss Anlasserkontakt abfragen
150
// **********************************************
151
int status_zs_anl(void)
152
{
153
  uint16_t warten = 1; // Anzahl Schleifendurchläufe * ms = Gesamtdauer
154
 
155
  while( (PINB & (1<<PINB0)) && (warten != 0) ) // Solange Eingangssignal erkannt und Zeit nicht abgelaufen
156
  {
157
    _delay_ms(25);
158
    warten--;
159
  }
160
161
  // Signal immer noch vorhanden UND Zeit abgelaufen? (sonst fehlen 25ms)
162
  if ( (PINB & (1<<PINB0)) && (warten == 0) )
163
    return 1;
164
  else
165
    return 0;
166
}
167
168
169
170
// ****************************************
171
// FUNKTION: Status von BMW Taster abfragen
172
// ****************************************
173
int status_bmw_taster(void)
174
{
175
  uint16_t warten = 1; // Anzahl Schleifendurchläufe * ms = Gesamtdauer
176
 
177
  while( (PINC & (1<<PINC3)) && (PINC & (1<<PINC4)) && (warten != 0) ) // Solange Eingangssignal erkannt und Zeit nicht abgelaufen
178
  {
179
    _delay_ms(25);
180
    warten--;
181
  }
182
183
  // Signal immer noch vorhanden UND Zeit abgelaufen? (sonst fehlen 25ms)
184
  if ( (PINC & (1<<PINC3)) && (PINC & (1<<PINC4)) && (warten == 0) )
185
    return 1;
186
  else
187
    return 0;
188
}
189
190
191
192
// ************************************
193
// FUNKTION: Motor starten ("Anlassen")
194
// ************************************
195
int anlassen(void)
196
{
197
  uint16_t warten = 400; // Anzahl Schleifendurchläufe * ms = Gesamtdauer
198
  
199
  // Nochmal zur Sicherheit nachsehen, ob D+61E kein Signal hat
200
  // (Wenn Motor anlaufen gelassen wird und sich dadurch die LiMa dreht, darf der Anlasser nicht reinrumpeln)
201
  if( !status_lima() )
202
  {  
203
    PORTC |= (1<<PC1); // Anlasserrelais einschalten
204
    
205
    // Startvorgang abbrechen, wenn Pedal AUS, D+61E EIN, Zeitlimit erreicht
206
    while( status_pedal() && !status_lima() && warten != 0 )
207
    {      
208
      _delay_ms(25); // Warten
209
210
      PORTD = PIND ^ (1<<PIND4); // Betriebs LED blinken lassen
211
212
      warten--; // Runterzählen, und nach xx Durchläufen Startvorgang abbrechen
213
    }
214
215
    PORTC &= ~(1<<PC1); // Anlasserrelais AUS
216
    
217
    PORTD |= (1<<PD4); // Betriebs LED einschalten, falls im "Aus"-Zustand aus Schleife ausgestiegen
218
    
219
  }
220
221
  return 0;
222
}
223
224
225
226
// *************
227
// Hauptprogramm
228
// *************
229
int main(void) 
230
{ 
231
232
233
234
// ********
235
// Ausgänge
236
// ********
237
  
238
  DDRC |= (1<<PC0); // PC0 Zündungsrelais
239
  DDRC |= (1<<PC1); // PC1 Anlasserrelais
240
241
  DDRD |= (1<<PD2); // PD2 LED OUT +
242
  DDRD |= (1<<PD3); // PD3 LED OUT -
243
  DDRD |= (1<<PD4); // PD4 Betriebs LED
244
245
246
247
// ********
248
// Eingänge
249
// ********
250
251
  // PB0 vom Zündschloss Anlasserkontakt
252
  // PC3 BMW Taster Hall OUT 1 (ist LOW wenn gedrückt!)
253
  // PC4 BMW Taster Hall OUT 2 (ist LOW wenn gedrückt!)
254
  // PD0 D+61E
255
  // PD1 Pedal
256
  // PD5 vom Standard-Taster
257
258
259
260
// Pullup-Widerstände aktivieren für Hall-Sensor-Eingänge
261
PORTC |= (1<<PC3);
262
PORTC |= (1<<PC4);
263
264
// Betriebs LED
265
PORTD |= (1<<PD4);
266
267
268
// Zündung einschalten (Je nach Wunsch. Kann auch wegfallen.)
269
// PORTC |= (1<<PC0);
270
    
271
272
273
  // *************
274
  // Hauptschleife
275
  // *************
276
  while(1)
277
  {
278
    
279
    // Pedal nicht betätigt?
280
    if ( !status_pedal() && durchlauf != 1 )
281
    {
282
  
283
      // Zündung AUS?
284
      if ( !status_zuendung() )
285
      {
286
        // Taster gedrückt? (BMW Taster oder Standardtaster oder Zündschloss-Anlasser)
287
        if ( status_standardtaster() )
288
        {
289
290
          // Zündung einschalten
291
          zuendung(1);
292
293
          // Ab jetzt nichts weiteres mehr machen sondern Programmdurchlauf abwarten
294
          durchlauf = 1;
295
296
        }
297
298
      } 
299
300
301
302
      // Zündung EIN?
303
      if ( status_zuendung() && durchlauf != 1 )
304
      {
305
306
        // Taster gedrückt? (BMW Taster oder Standardtaster)
307
        if ( status_standardtaster() )
308
        {
309
310
          // Zündung ausschalten
311
          zuendung(0);
312
313
          // Ab jetzt nichts weiteres mehr machen sondern Programmdurchlauf abwarten
314
          durchlauf = 1;
315
316
        }
317
  
318
      }
319
320
    } 
321
322
323
324
    // Pedal EIN?
325
    if ( status_pedal() && (durchlauf != 1) )
326
    {
327
328
      // Zündung AUS?
329
      if ( !status_zuendung() )
330
      {
331
332
        // Taster gedrückt? (BMW Taster oder Standardtaster oder Zündschloss-Anlasser)
333
        if ( status_standardtaster() )
334
        {
335
336
          // Zündung einschalten
337
          zuendung(1);
338
339
          // Pause zwischen "Zündung" und "Anlassen"
340
          _delay_ms(250);
341
342
          // Anlassen
343
          anlassen();
344
345
          // Ab jetzt nichts weiteres mehr machen sondern Programmdurchlauf abwarten
346
          durchlauf = 1;
347
348
        }
349
350
      }
351
352
      // Zündung EIN?
353
      if ( status_zuendung() && (durchlauf != 1) )
354
      {
355
356
        // Taster gedrückt? (BMW Taster oder Standardtaster oder Zündschloss-Anlasser)
357
        if ( status_standardtaster() || status_zs_anl() )
358
        {
359
360
          // D+61E EIN?
361
          if ( status_lima() )
362
          {
363
364
            // Zündung ausschalten
365
            zuendung(0);
366
367
            // Ab jetzt nichts weiteres mehr machen sondern Programmdurchlauf abwarten
368
            durchlauf = 1;
369
370
          }
371
        
372
          // D+61E AUS?
373
          if ( !status_lima() && (durchlauf != 1) )
374
          {
375
376
            // Anlassen
377
            anlassen();
378
379
            // Ab jetzt nichts weiteres mehr machen sondern Programmdurchlauf abwarten
380
            durchlauf = 1;
381
382
          }
383
384
        }
385
386
      }
387
    
388
    }
389
390
391
392
  // Programmdurchlauf Ende. 
393
394
  // Data Register der Eingangspins löschen, damit da keine Restspannung am PIN übrigbleibt
395
  // ohne diese Löschung verbleiben nach Startvorgang 1,12 Volt am PIN, warum auch immer...
396
397
  PORTD &= ~(1<<PD0); 
398
  PORTD &= ~(1<<PD1);  
399
  PORTD &= ~(1<<PD5);  
400
  PORTB &= ~(1<<PB0);  
401
402
403
404
  // Erneuter Einstieg erst wieder möglich, wenn alle Taster losgelassen.
405
  if( status_standardtaster_offen() )
406
  {
407
    durchlauf = 0;
408
  }  
409
  
410
  // Hauptschleife Ende
411
  }
412
  
413
  // Status BMW Taster hier einfügen
414
415
416
  return 0;
417
418
} // Ende int main