Subversion Repositories BL-Ctrl

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
60 hbuss 1
/*#######################################################################################
2
Flight Control
3
#######################################################################################*/
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// + Regler für Brushless-Motoren
6
// + ATMEGA8 mit 8MHz
7
// + Nur für den privaten Gebrauch
8
// + Copyright (c) 12.2007 Holger Buss
9
// + www.MikroKopter.com
10
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation), 
12
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist. 
13
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt 
14
// + bzgl. der Nutzungsbedingungen aufzunehmen. 
15
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
16
// + Verkauf von Luftbildaufnahmen, usw.
17
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
18
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht, 
19
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
20
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
22
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
23
// + eindeutig als Ursprung verlinkt werden
24
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
25
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
26
// + Benutzung auf eigene Gefahr
27
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
28
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur 
30
// + mit unserer Zustimmung zulässig
31
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
33
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
34
// + Redistributions of source code (with or without modifications) must retain the above copyright notice, 
35
// + this list of conditions and the following disclaimer.
36
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
37
// +     from this software without specific prior written permission.
38
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet 
39
// +     for non-commercial use (directly or indirectly)
40
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted 
41
// +     with our written permission
42
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be 
43
// +     clearly linked as origin 
44
// +   * porting to systems other than hardware from www.mikrokopter.de is not allowed
45
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
46
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
49
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
54
// +  POSSIBILITY OF SUCH DAMAGE. 
55
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 ingob 56
 
57
#include "main.h"
58
 
63 hbuss 59
unsigned int  PWM = 0;
58 hbuss 60
unsigned int  Strom = 0,RuheStrom; //ca. in 0,1A
1 ingob 61
unsigned char Strom_max = 0;
51 holgerb 62
unsigned char Mittelstrom = 0;
1 ingob 63
unsigned int  Drehzahl = 0;  // in 100UPM  60 = 6000
64
unsigned int  KommutierDelay = 10;
65
unsigned int  I2C_Timeout = 0;
23 ingob 66
unsigned int SIO_Timeout = 0;
1 ingob 67
unsigned int  SollDrehzahl = 0;
68
unsigned int  IstDrehzahl = 0;
69
unsigned int  DrehZahlTabelle[256];//vorberechnete Werte zur Drehzahlerfassung
70
unsigned char ZeitFuerBerechnungen = 1;
71
unsigned char MotorAnwerfen = 0;
72
unsigned char MotorGestoppt = 1;
73
unsigned char MaxPWM = MAX_PWM;
74
unsigned int  CntKommutierungen = 0;
75
unsigned int  SIO_Drehzahl = 0;
76
unsigned char ZeitZumAdWandeln = 1;
24 ingob 77
unsigned char MotorAdresse = 1;
50 holgerb 78
unsigned char PPM_Betrieb = 1;
1 ingob 79
 
80
//############################################################################
81
//
82
void SetPWM(void)
83
//############################################################################
84
{
85
    unsigned char tmp_pwm;
86
    tmp_pwm = PWM;
87
    if(tmp_pwm > MaxPWM)    // Strombegrenzung
88
        {
89
        tmp_pwm = MaxPWM;
90
        PORTC |= ROT;
91
        }
92
    if(Strom > MAX_STROM)   // Strombegrenzung
93
        {
94
        OCR1A = 0; OCR1B = 0; OCR2  = 0;
95
        PORTC |= ROT;
96
        Strom--;
97
        }
98
    else
99
        {
100
        #ifdef  _32KHZ 
101
        OCR1A =  tmp_pwm; OCR1B =  tmp_pwm; OCR2  = tmp_pwm;
102
        #endif 
103
 
104
        #ifdef  _16KHZ 
50 holgerb 105
        //OCR1A = 2 * (int)tmp_pwm; OCR1B = 2 * (int)tmp_pwm; OCR2  = tmp_pwm;
106
        OCR1A =  tmp_pwm; OCR1B =  tmp_pwm; OCR2  = tmp_pwm;
1 ingob 107
        #endif 
108
        }
109
}
110
 
111
//############################################################################
112
//
113
void PWM_Init(void)
114
//############################################################################
115
{
116
    PWM_OFF;
50 holgerb 117
    TCCR1B = (1 << CS10) | (0 << CS11) | (0 << CS12) | (0 << WGM12) |
1 ingob 118
             (0 << WGM13) | (0<< ICES1) | (0 << ICNC1);
50 holgerb 119
/*    TCCR1B = (1 << CS10) | (0 << CS11) | (0 << CS12) | (1 << WGM12) |
120
             (0 << WGM13) | (0<< ICES1) | (0 << ICNC1);
121
*/
1 ingob 122
}
123
 
124
//############################################################################
125
//
126
void Wait(unsigned char dauer)
127
//############################################################################
128
{
129
    dauer = (unsigned char)TCNT0 + dauer;
130
    while((TCNT0 - dauer) & 0x80);
131
}
132
 
133
//############################################################################
134
//
135
void Anwerfen(unsigned char pwm)
136
//############################################################################
137
{
138
    unsigned long timer = 300,i;
139
    DISABLE_SENSE_INT;
140
    PWM = 5;
141
    SetPWM();
142
    Manuell();
143
    Delay_ms(200);
144
    PWM = pwm;
145
    while(1)
146
        {
147
        for(i=0;i<timer; i++)
148
            {
149
            if(!UebertragungAbgeschlossen)  SendUart();
150
            else DatenUebertragung();
151
            Wait(100);  // warten
152
            }
153
        timer-= timer/15+1;
154
        if(timer < 25) { if(TEST_MANUELL) timer = 25; else return; }
155
 
156
        Manuell();
157
        Phase++;
158
        Phase %= 6;
159
        AdConvert();
160
        PWM = pwm;
161
        SetPWM();
162
        if(SENSE)
163
            {
164
            PORTD ^= GRUEN;
165
            }
166
        }
167
}
168
 
50 holgerb 169
/*
170
#define SENSE_A ADMUX = 0;
171
#define SENSE_B ADMUX = 1;
172
#define SENSE_C ADMUX = 2;
173
 
174
#define ClrSENSE            ACSR |= 0x10
175
#define SENSE               ((ACSR & 0x10))
176
#define SENSE_L             (!(ACSR & 0x20))
177
#define SENSE_H             ((ACSR & 0x20))
178
*/
179
 
180
void RotBlink(unsigned char anz)
181
{
182
sei(); // Interrupts ein
183
 while(anz--)
184
  {
185
   PORTC |= ROT;
186
   Delay_ms(300);    
187
   PORTC &= ~ROT;
188
   Delay_ms(300);    
189
  }
190
   Delay_ms(1000);    
191
}
192
 
58 hbuss 193
#define TEST_STROMGRENZE 120
50 holgerb 194
unsigned char DelayM(unsigned int timer)
195
{
196
 while(timer--)
197
  {
198
   FastADConvert();
58 hbuss 199
   if(Strom > (TEST_STROMGRENZE + RuheStrom))
50 holgerb 200
       {
51 holgerb 201
        FETS_OFF;
50 holgerb 202
        return(1);
203
       }
204
  }
205
 return(0);  
206
}
207
 
208
unsigned char Delay(unsigned int timer)
209
{
210
 while(timer--)
211
  {
51 holgerb 212
//   if(SENSE_H) { PORTC |= ROT; } else { PORTC &= ~ROT;}
50 holgerb 213
  }
214
 return(0);  
215
}
216
 
58 hbuss 217
/*
51 holgerb 218
void ShowSense(void)
219
{
220
 if(SENSE_H) { PORTC |= ROT; } else { PORTC &= ~ROT;}
50 holgerb 221
 
51 holgerb 222
}
58 hbuss 223
*/
51 holgerb 224
#define HIGH_A_EIN PORTB |= 0x08
225
#define HIGH_B_EIN PORTB |= 0x04
226
#define HIGH_C_EIN PORTB |= 0x02
227
#define LOW_A_EIN  PORTD |= 0x08
228
#define LOW_B_EIN  PORTD |= 0x10
229
#define LOW_C_EIN  PORTD |= 0x20
230
 
50 holgerb 231
void MotorTon(void)
1 ingob 232
//############################################################################
50 holgerb 233
{
51 holgerb 234
    unsigned char ADR_TAB[5] = {0,0,2,1,3};
50 holgerb 235
    unsigned int timer = 300,i;
51 holgerb 236
    unsigned int t = 0;
58 hbuss 237
    unsigned char anz = 0,MosfetOkay = 0, grenze = 50;
51 holgerb 238
 
239
    PORTC &= ~ROT;
240
    Delay_ms(300 * ADR_TAB[MotorAdresse]);    
50 holgerb 241
    DISABLE_SENSE_INT;
242
    cli();//Globale Interrupts Ausschalten
243
    uart_putchar('\n');
244
    STEUER_OFF;
58 hbuss 245
    Strom_max = 0;
246
    DelayM(50);
247
    RuheStrom = Strom_max;
248
//    uart_putchar(RuheStrom + 'A');
50 holgerb 249
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
250
//+ High-Mosfets auf Kurzschluss testen
251
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
252
    Strom = 0;
71 hbuss 253
/*
51 holgerb 254
    LOW_B_EIN;
255
    HIGH_A_EIN;
50 holgerb 256
    if(DelayM(3))
257
       {
258
        anz = 1;
51 holgerb 259
        uart_putchar('1');
50 holgerb 260
       }
51 holgerb 261
    FETS_OFF;
262
    Delay(1000);
50 holgerb 263
    Strom = 0;
51 holgerb 264
    LOW_A_EIN;
265
    HIGH_B_EIN;
50 holgerb 266
    if(DelayM(3))
267
       {
268
        anz = 2;
51 holgerb 269
        uart_putchar('2');
50 holgerb 270
       }
51 holgerb 271
    FETS_OFF;
272
    Delay(1000);
50 holgerb 273
    Strom = 0;
51 holgerb 274
    LOW_B_EIN; // Low C ein
275
    HIGH_C_EIN; // High B ein
50 holgerb 276
    if(DelayM(3))
277
       {
278
        anz = 3;
51 holgerb 279
        uart_putchar('3');
50 holgerb 280
       }
51 holgerb 281
    FETS_OFF;
282
    Delay(1000);
283
    LOW_A_EIN; // Low  A ein; und A gegen C
284
    HIGH_C_EIN; // High C ein
50 holgerb 285
    if(DelayM(3))
286
       {
287
        anz = 3;
51 holgerb 288
        uart_putchar('7');
50 holgerb 289
       }
51 holgerb 290
    FETS_OFF;
291
    DelayM(10000);
71 hbuss 292
 
51 holgerb 293
if(anz) while(1) RotBlink(anz);  // bei Kurzschluss nicht starten
71 hbuss 294
*/
50 holgerb 295
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
51 holgerb 296
//+ LOW-Mosfets auf Schalten und Kurzschluss testen
50 holgerb 297
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58 hbuss 298
 if(UDR == ' ') {t = 65535; grenze = 40; uart_putchar('_');} else t = 1000; // Ausführlicher Test
51 holgerb 299
 Strom = 0;
300
 for(i=0;i<t;i++)
301
 {
302
  LOW_A_EIN;
303
  DelayM(1);
304
  FETS_OFF;
305
  Delay(5);
306
  HIGH_A_EIN;
307
  DelayM(1);
308
  FETS_OFF;
58 hbuss 309
  if(Strom > grenze + RuheStrom) {anz = 4; uart_putchar('4'); break;}
51 holgerb 310
  Delay(5);
311
 }
312
 Delay(10000);
50 holgerb 313
 
51 holgerb 314
 Strom = 0;
315
 for(i=0;i<t;i++)
316
 {
317
  LOW_B_EIN;
318
  DelayM(1);
319
  FETS_OFF;
320
  Delay(5);
321
  HIGH_B_EIN;
322
  DelayM(1);
323
  FETS_OFF;
58 hbuss 324
  if(Strom > grenze + RuheStrom) {anz = 5; uart_putchar('5'); break;}
51 holgerb 325
  Delay(5);
326
 }
50 holgerb 327
 
51 holgerb 328
 Strom = 0;
329
 Delay(10000);
330
 
331
 for(i=0;i<t;i++)
332
 {
333
  LOW_C_EIN;
334
  DelayM(1);
335
  FETS_OFF;
336
  Delay(5);
337
  HIGH_C_EIN;
338
  DelayM(1);
339
  FETS_OFF;
58 hbuss 340
  if(Strom > grenze + RuheStrom) {anz = 6; uart_putchar('6'); break;}
51 holgerb 341
  Delay(5);
342
 }
343
 
50 holgerb 344
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
345
//+ High-Mosfets auf Schalten testen
346
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
347
    SENSE_A;
51 holgerb 348
    FETS_OFF;
349
    LOW_B_EIN; // Low B ein
350
    LOW_C_EIN; // Low C ein
50 holgerb 351
    Strom = 0;
51 holgerb 352
#define TONDAUER  40000    
71 hbuss 353
#define SOUND_E 1  // 1
51 holgerb 354
#define SOUND1_A 300
355
#define SOUND2_A 330
356
#define SOUND3_A 360
357
 
50 holgerb 358
    for(i=0; i< (TONDAUER / SOUND2_A) ; i++)
359
     {
51 holgerb 360
      HIGH_A_EIN; // Test A
50 holgerb 361
      Delay(SOUND_E);
51 holgerb 362
      if(MessAD(0) > 50) { MosfetOkay |= 0x01; } else { MosfetOkay &= ~0x01;};
50 holgerb 363
      PORTB = 0;
51 holgerb 364
      Delay(SOUND1_A);
50 holgerb 365
     }
51 holgerb 366
    FETS_OFF;
367
 
368
    LOW_A_EIN; // Low A ein
369
    LOW_C_EIN; // Low C ein
50 holgerb 370
    for(i=0; i<(TONDAUER / SOUND1_A); i++)
371
     {
51 holgerb 372
      HIGH_B_EIN; // Test B
50 holgerb 373
      Delay(SOUND_E);
51 holgerb 374
      if(MessAD(1) > 50) { MosfetOkay |= 0x02; } else { MosfetOkay &= ~0x02;};
50 holgerb 375
      PORTB = 0;
376
      Delay(SOUND1_A);
377
     }
378
 
51 holgerb 379
    FETS_OFF;
380
    LOW_A_EIN; // Low A ein
381
    LOW_B_EIN; // Low B ein
50 holgerb 382
    for(i=0; i<(TONDAUER / SOUND3_A); i++)
383
     {
51 holgerb 384
      HIGH_C_EIN; // Test C
50 holgerb 385
      Delay(SOUND_E);
51 holgerb 386
      if(MessAD(2) > 50) { MosfetOkay |= 0x04; } else { MosfetOkay &= ~0x04;};
50 holgerb 387
      PORTB = 0;
51 holgerb 388
      Delay(SOUND2_A);
50 holgerb 389
     }
51 holgerb 390
    FETS_OFF;
50 holgerb 391
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
392
//+ Low-Mosfets auf Schalten testen
393
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
394
    SENSE_B;
51 holgerb 395
    LOW_A_EIN; // Low A ein
50 holgerb 396
    for(i=0; i< (TONDAUER / SOUND2_A) ; i++)
397
     {
51 holgerb 398
      HIGH_B_EIN; // Test B
50 holgerb 399
      Delay(SOUND_E);
51 holgerb 400
      if(MessAD(0) > 50) { MosfetOkay &= ~0x08;} else { MosfetOkay |= 0x08;};
50 holgerb 401
      PORTB = 0;
402
      Delay(SOUND2_A);
403
     }
51 holgerb 404
 
405
//++++++++++++++++++++++++++++++++++++
406
    LOW_C_EIN; // Low C ein
407
    for(i=0; i<(TONDAUER / SOUND1_A); i++)
50 holgerb 408
     {
51 holgerb 409
      HIGH_B_EIN; // Test B
50 holgerb 410
      Delay(SOUND_E);
51 holgerb 411
      if(MessAD(2) > 50) { MosfetOkay &= ~0x20;} else { MosfetOkay |= 0x20;};
50 holgerb 412
      PORTB = 0;
413
      Delay(SOUND3_A);
414
     }
51 holgerb 415
    FETS_OFF;
416
//++++++++++++++++++++++++++++++++++++
417
    FETS_OFF;
418
    LOW_B_EIN; // Low B ein
419
    for(i=0; i<(TONDAUER / SOUND3_A); i++)
50 holgerb 420
     {
51 holgerb 421
      HIGH_C_EIN; // Test C
50 holgerb 422
      Delay(SOUND_E);
51 holgerb 423
      if(MessAD(1) > 50) { MosfetOkay &= ~0x10;} else { MosfetOkay |= 0x10;};
50 holgerb 424
      PORTB = 0;
51 holgerb 425
      Delay(SOUND3_A);
50 holgerb 426
     }
51 holgerb 427
    FETS_OFF;
428
//++++++++++++++++++++++++++++++++++++
50 holgerb 429
 
51 holgerb 430
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
50 holgerb 431
    sei();//Globale Interrupts Einschalten
51 holgerb 432
//    Delay_ms(250 * MotorAdresse);    
433
/*
434
    LOW_A_EIN; // Low B ein
50 holgerb 435
#define SOUND8_A 650
436
    for(i=0; i<(TONDAUER / SOUND8_A); i++)
437
     {
51 holgerb 438
      HIGH_B_EIN; // Test B
439
      Delay(SOUND_E);
440
      PORTB = 0;
441
      Delay(SOUND8_A);
50 holgerb 442
     }
51 holgerb 443
*/
444
 Delay_ms(300 * (4-ADR_TAB[MotorAdresse]));    
58 hbuss 445
 if(!(MosfetOkay & 0x01))  { anz = 1; UDR='A'; } else
446
 if(!(MosfetOkay & 0x02))  { anz = 2; UDR='B'; } else
447
 if(!(MosfetOkay & 0x04))  { anz = 3; UDR='C'; } else
448
 if(!(MosfetOkay & 0x08))  { anz = 4; UDR='a'; } else
449
 if(!(MosfetOkay & 0x10))  { anz = 5; UDR='b'; } else
450
 if(!(MosfetOkay & 0x20))  { anz = 6; UDR='c'; }  
50 holgerb 451
 
58 hbuss 452
 if(anz) Delay_ms(1000);
50 holgerb 453
 
51 holgerb 454
 RotBlink(anz);
455
 uart_putchar('.');
50 holgerb 456
}
457
 
458
//############################################################################
1 ingob 459
//
460
unsigned char SollwertErmittlung(void)
461
//############################################################################
462
{
463
    static unsigned int sollwert = 0;
464
    unsigned int ppm;
465
    if(!I2C_Timeout)   // bei Erreichen von 0 ist der Wert ungültig
466
        {
467
        if(SIO_Timeout)  // es gibt gültige SIO-Daten
468
            {
50 holgerb 469
             sollwert =  (MAX_PWM * (unsigned int) SIO_Sollwert) / 200;  // skalieren auf 0-200 = 0-255
470
             PPM_Betrieb = 0;
471
             ICP_INT_DISABLE;
472
             PORTC &= ~ROT;
1 ingob 473
            }
474
        else
50 holgerb 475
            if(anz_ppm_werte > 20)  // es gibt gültige PPM-Daten
1 ingob 476
                {
50 holgerb 477
                PPM_Betrieb = 1;
1 ingob 478
                ppm = PPM_Signal;
479
                if(ppm > 300) ppm =   0;  // ungültiges Signal
480
                if(ppm > 200) ppm = 200;
481
                if(ppm <= MIN_PPM) sollwert = 0;
482
                else
483
                    {
484
                    sollwert = (int) MIN_PWM + ((MAX_PWM - MIN_PWM) * (ppm - MIN_PPM)) / (190 - MIN_PPM);
485
                    }
486
                PORTC &= ~ROT;
487
                }
488
            else   // Kein gültiger Sollwert
489
                {
50 holgerb 490
                 if(!TEST_SCHUB) { if(sollwert) sollwert--; }  
491
                 PORTC |= ROT;
1 ingob 492
                }
493
        }
494
    else // I2C-Daten sind gültig
495
        {
496
        sollwert = I2C_RXBuffer;
50 holgerb 497
        PPM_Betrieb = 0;
1 ingob 498
        PORTC &= ~ROT;
50 holgerb 499
        ICP_INT_DISABLE;
1 ingob 500
        }
501
    if(sollwert > MAX_PWM) sollwert = MAX_PWM;
502
    return(sollwert);
503
}
504
 
505
void DebugAusgaben(void)
506
{
507
    DebugOut.Analog[0] = Strom;
508
    DebugOut.Analog[1] = Mittelstrom;
509
    DebugOut.Analog[2] = SIO_Drehzahl;
510
    DebugOut.Analog[3] = PPM_Signal;
72 hbuss 511
    DebugOut.Analog[4] = OCR2;
1 ingob 512
}
513
 
514
 
515
//############################################################################
516
//Hauptprogramm
517
int main (void)
518
//############################################################################
519
{
520
    char altPhase = 0;
521
    int test = 0;
522
    unsigned int MinUpmPulse,Blink,TestschubTimer;
523
    unsigned int Blink2,MittelstromTimer,DrehzahlMessTimer,MotorGestopptTimer;
524
 
525
    DDRC  = 0x08;
526
    PORTC = 0x08;
527
    DDRD  = 0xBA;
26 ingob 528
    PORTD = 0x00;
1 ingob 529
    DDRB  = 0x0E;
530
    PORTB = 0x31;
24 ingob 531
 
532
#if (MOTORADRESSE == 0)
533
    PORTB |= (ADR1 + ADR2);   // Pullups für Adresswahl
43 holgerb 534
    for(test=0;test<500;test++);
24 ingob 535
    if (PINB & ADR1)
536
         {
537
           if (PINB & ADR2) MotorAdresse = 1;
538
            else MotorAdresse = 2;
539
         }
540
         else
541
         {
542
           if (PINB & ADR2) MotorAdresse = 3;
543
            else MotorAdresse = 4;
544
         }
545
#else
546
    MotorAdresse  = MOTORADRESSE;
547
#endif
1 ingob 548
 
549
    UART_Init();
550
    Timer0_Init();
50 holgerb 551
    sei();//Globale Interrupts Einschalten
1 ingob 552
 
553
    // Am Blinken erkennt man die richtige Motoradresse
50 holgerb 554
/*
1 ingob 555
    for(test=0;test<5;test++)
556
        {
24 ingob 557
        if(test == MotorAdresse) PORTD |= GRUEN;
1 ingob 558
        Delay_ms(150);
559
        PORTD &= ~GRUEN;
560
        Delay_ms(250);
561
        }      
562
 
563
    Delay_ms(500);
50 holgerb 564
*/  
18 ingob 565
   // UART_Init();  // war doppelt
1 ingob 566
    PWM_Init();
567
 
568
    InitIC2_Slave(0x50);                           
569
    InitPPM();
570
 
571
    Blink             = SetDelay(101);    
572
    Blink2            = SetDelay(102);
573
    MinUpmPulse       = SetDelay(103);
574
    MittelstromTimer  = SetDelay(254);
575
    DrehzahlMessTimer = SetDelay(1005);
576
    TestschubTimer    = SetDelay(1006);
50 holgerb 577
    while(!CheckDelay(MinUpmPulse))
578
    {
579
     if(SollwertErmittlung()) break;
580
    }
581
    ;
1 ingob 582
    PORTD |= GRUEN;
583
    PWM = 0;
584
 
585
    SetPWM();
586
 
587
    SFIOR = 0x08;  // Analog Comperator ein
588
    ADMUX = 1;
589
 
590
    MinUpmPulse = SetDelay(10);
591
    DebugOut.Analog[1] = 1;
592
    PPM_Signal = 0;
593
 
50 holgerb 594
    if(!SollwertErmittlung()) MotorTon();
58 hbuss 595
//MotorTon();    
596
    PORTB = 0x31; // Pullups wieder einschalten
50 holgerb 597
 
1 ingob 598
    // zum Test der Hardware; Motor dreht mit konstanter Drehzahl ohne Regelung
599
    if(TEST_MANUELL)    Anwerfen(TEST_MANUELL);  // kommt von dort nicht wieder
600
 
601
    while (1)
602
        {
51 holgerb 603
//ShowSense();
604
 
1 ingob 605
        if(!TEST_SCHUB)   PWM = SollwertErmittlung();
606
        //I2C_TXBuffer = PWM; // Antwort über I2C-Bus
607
        if(MANUELL_PWM)   PWM = MANUELL_PWM;
608
 
609
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
610
        if(Phase != altPhase)   // es gab eine Kommutierung im Interrupt
611
            {
612
            MotorGestoppt = 0;
613
            ZeitFuerBerechnungen = 0;    // direkt nach einer Kommutierung ist Zeit 
58 hbuss 614
            MinUpmPulse = SetDelay(250);  // Timeout, falls ein Motor stehen bleibt
1 ingob 615
            altPhase = Phase;
616
            }
617
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
618
        if(!PWM)    // Sollwert == 0
619
            {
620
            MotorAnwerfen = 0;      // kein Startversuch
621
            ZeitFuerBerechnungen = 0;
622
            // nach 1,5 Sekunden den Motor als gestoppt betrachten 
18 ingob 623
            if(CheckDelay(MotorGestopptTimer))
1 ingob 624
                {
625
                DISABLE_SENSE_INT;
626
                MotorGestoppt = 1;  
627
                STEUER_OFF;
628
                }
629
            }
630
        else
631
            {
632
            if(MotorGestoppt) MotorAnwerfen = 1;        // Startversuch
633
            MotorGestopptTimer = SetDelay(1500);
634
            }
635
 
636
        if(MotorGestoppt && !TEST_SCHUB) PWM = 0;
72 hbuss 637
if(SIO_Drehzahl > 120 && PWM > )
1 ingob 638
        SetPWM();
639
        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
640
        if(!ZeitFuerBerechnungen++)
641
            {
642
            if(MotorGestoppt) PORTD |= GRUEN; //else PORTD &= ~GRUEN;
643
            if(SIO_DEBUG)
644
                {
645
                DebugAusgaben();  // welche Werte sollen angezeigt werden?
646
                if(!UebertragungAbgeschlossen)  SendUart();
647
                else DatenUebertragung();
648
                }
649
            // Berechnen des Mittleren Stroms zur (langsamen) Strombegrenzung
650
            if(CheckDelay(MittelstromTimer))  
651
                {
652
                MittelstromTimer = SetDelay(50); // alle 50ms
653
                if(Mittelstrom <  Strom) Mittelstrom++;// Mittelwert des Stroms bilden
654
                else if(Mittelstrom >  Strom) Mittelstrom--;
72 hbuss 655
                if((Strom > MAX_STROM)) MaxPWM -= MaxPWM / 32;              
58 hbuss 656
                if((Mittelstrom > LIMIT_STROM))// Strom am Limit?
1 ingob 657
                    {
58 hbuss 658
                    if(MaxPWM) MaxPWM--;// dann die Maximale PWM herunterfahren
1 ingob 659
                    PORTC |= ROT;
660
                    }
661
                else
662
                    {
663
                    if(MaxPWM < MAX_PWM) MaxPWM++;
664
                    }
665
                }
666
 
667
            if(CheckDelay(DrehzahlMessTimer))   // Ist-Drehzahl bestimmen
668
                {
669
                DrehzahlMessTimer = SetDelay(10);
58 hbuss 670
                SIO_Drehzahl = CntKommutierungen;//(6 * CntKommutierungen) / (POLANZAHL / 2);
1 ingob 671
                CntKommutierungen = 0;
71 hbuss 672
               // if(PPM_Timeout == 0) // keine PPM-Signale
1 ingob 673
                ZeitZumAdWandeln = 1;
674
                }
58 hbuss 675
          if(TEST_SCHUB)
676
           {
1 ingob 677
            if(CheckDelay(TestschubTimer))  
678
                {
679
                TestschubTimer = SetDelay(1500);
680
                    switch(test)
681
                        {
682
                        case 0: PWM = 50; test++; break;
683
                        case 1: PWM = 130; test++; break;
684
                        case 2: PWM = 60;  test++; break;
685
                        case 3: PWM = 140; test++; break;
686
                        case 4: PWM = 150; test = 0; break;
687
                        default: test = 0;
688
                        }
689
                }
58 hbuss 690
            }  
691
          // Motor Stehen geblieben
1 ingob 692
            if((CheckDelay(MinUpmPulse) && SIO_Drehzahl == 0) || MotorAnwerfen)
693
                {
694
                MotorGestoppt = 1;    
695
                DISABLE_SENSE_INT;
696
                MinUpmPulse = SetDelay(100);        
697
                if(MotorAnwerfen)
698
                    {
699
                    PORTC &= ~ROT;
700
                    MotorAnwerfen = 0;
701
                    Anwerfen(10);
702
                    PORTD |= GRUEN;
703
                    MotorGestoppt = 0;    
704
                    Phase--;
705
                    PWM = 1;
706
                    SetPWM();
707
                    SENSE_TOGGLE_INT;
708
                    ENABLE_SENSE_INT;
72 hbuss 709
                    CntKommutierungen = 0;
710
                    MinUpmPulse = SetDelay(10); //20
1 ingob 711
                    while(!CheckDelay(MinUpmPulse)); // kurz Synchronisieren
43 holgerb 712
                    PWM = 15;
1 ingob 713
                    SetPWM();
43 holgerb 714
                    MinUpmPulse = SetDelay(300);
1 ingob 715
                    while(!CheckDelay(MinUpmPulse)); // kurz Durchstarten
18 ingob 716
 
717
                                    // Drehzahlmessung wieder aufsetzen
718
                    DrehzahlMessTimer = SetDelay(50);
1 ingob 719
                    altPhase = 7;
720
                    }
721
                }
722
            } // ZeitFuerBerechnungen
723
        } // while(1) - Hauptschleife
724
}
725