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
73 hbuss 42
// +   * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be 
60 hbuss 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;
73 hbuss 79
unsigned char HwVersion;
80
unsigned char IntRef = 0;
81
unsigned int MinUpmPulse;
1 ingob 82
//############################################################################
83
//
84
void SetPWM(void)
85
//############################################################################
86
{
87
    unsigned char tmp_pwm;
88
    tmp_pwm = PWM;
89
    if(tmp_pwm > MaxPWM)    // Strombegrenzung
90
        {
91
        tmp_pwm = MaxPWM;
92
        PORTC |= ROT;
93
        }
94
    if(Strom > MAX_STROM)   // Strombegrenzung
95
        {
73 hbuss 96
        OCR1A = 0; OCR1B = 0; OCR2 = 0;
97
        PORTD &= ~0x38;
1 ingob 98
        PORTC |= ROT;
73 hbuss 99
        DebugOut.Analog[6]++;
1 ingob 100
        Strom--;
101
        }
102
    else
103
        {
104
        #ifdef  _32KHZ 
105
        OCR1A =  tmp_pwm; OCR1B =  tmp_pwm; OCR2  = tmp_pwm;
106
        #endif 
107
 
108
        #ifdef  _16KHZ 
50 holgerb 109
        //OCR1A = 2 * (int)tmp_pwm; OCR1B = 2 * (int)tmp_pwm; OCR2  = tmp_pwm;
110
        OCR1A =  tmp_pwm; OCR1B =  tmp_pwm; OCR2  = tmp_pwm;
1 ingob 111
        #endif 
112
        }
113
}
114
 
73 hbuss 115
void DebugAusgaben(void)
116
{
117
    DebugOut.Analog[0] = Strom;
118
    DebugOut.Analog[1] = Mittelstrom;
119
    DebugOut.Analog[2] = SIO_Drehzahl;
120
    DebugOut.Analog[3] = PPM_Signal;
121
    DebugOut.Analog[4] = OCR2;
122
//    DebugOut.Analog[5] = PWM;
123
}
124
 
1 ingob 125
//############################################################################
126
//
127
void PWM_Init(void)
128
//############################################################################
129
{
130
    PWM_OFF;
50 holgerb 131
    TCCR1B = (1 << CS10) | (0 << CS11) | (0 << CS12) | (0 << WGM12) |
1 ingob 132
             (0 << WGM13) | (0<< ICES1) | (0 << ICNC1);
50 holgerb 133
/*    TCCR1B = (1 << CS10) | (0 << CS11) | (0 << CS12) | (1 << WGM12) |
134
             (0 << WGM13) | (0<< ICES1) | (0 << ICNC1);
135
*/
1 ingob 136
}
137
 
138
//############################################################################
139
//
140
void Wait(unsigned char dauer)
141
//############################################################################
142
{
143
    dauer = (unsigned char)TCNT0 + dauer;
144
    while((TCNT0 - dauer) & 0x80);
145
}
146
 
73 hbuss 147
void RotBlink(unsigned char anz)
148
{
149
sei(); // Interrupts ein
150
 while(anz--)
151
  {
152
   PORTC |= ROT;
153
   Delay_ms(300);    
154
   PORTC &= ~ROT;
155
   Delay_ms(300);    
156
  }
157
   Delay_ms(1000);    
158
}
159
 
1 ingob 160
//############################################################################
161
//
73 hbuss 162
char Anwerfen(unsigned char pwm)
1 ingob 163
//############################################################################
164
{
165
    unsigned long timer = 300,i;
166
    DISABLE_SENSE_INT;
167
    PWM = 5;
168
    SetPWM();
169
    Manuell();
73 hbuss 170
//    Delay_ms(200);
171
                    MinUpmPulse = SetDelay(300);
172
                    while(!CheckDelay(MinUpmPulse))
173
                    {
174
                     FastADConvert();
175
                      if(Strom > 120)
176
                      {
177
                        STEUER_OFF; // Abschalten wegen Kurzschluss
178
                        RotBlink(10);
179
                        return(0);
180
                      }  
181
                    }
1 ingob 182
    PWM = pwm;
183
    while(1)
184
        {
185
        for(i=0;i<timer; i++)
186
            {
187
            if(!UebertragungAbgeschlossen)  SendUart();
188
            else DatenUebertragung();
189
            Wait(100);  // warten
190
            }
73 hbuss 191
        DebugAusgaben();
192
        FastADConvert();
193
        if(Strom > 60)
194
          {
195
            STEUER_OFF; // Abschalten wegen Kurzschluss
196
            RotBlink(10);
197
            return(0);
198
          }  
199
 
1 ingob 200
        timer-= timer/15+1;
73 hbuss 201
        if(timer < 25) { if(TEST_MANUELL) timer = 25; else return(1); }
1 ingob 202
        Manuell();
203
        Phase++;
204
        Phase %= 6;
205
        AdConvert();
206
        PWM = pwm;
207
        SetPWM();
208
        if(SENSE)
209
            {
210
            PORTD ^= GRUEN;
211
            }
212
        }
213
}
214
 
50 holgerb 215
/*
216
#define SENSE_A ADMUX = 0;
217
#define SENSE_B ADMUX = 1;
218
#define SENSE_C ADMUX = 2;
219
 
220
#define ClrSENSE            ACSR |= 0x10
221
#define SENSE               ((ACSR & 0x10))
222
#define SENSE_L             (!(ACSR & 0x20))
223
#define SENSE_H             ((ACSR & 0x20))
224
*/
225
 
226
 
58 hbuss 227
#define TEST_STROMGRENZE 120
50 holgerb 228
unsigned char DelayM(unsigned int timer)
229
{
230
 while(timer--)
231
  {
232
   FastADConvert();
58 hbuss 233
   if(Strom > (TEST_STROMGRENZE + RuheStrom))
50 holgerb 234
       {
51 holgerb 235
        FETS_OFF;
50 holgerb 236
        return(1);
237
       }
238
  }
239
 return(0);  
240
}
241
 
242
unsigned char Delay(unsigned int timer)
243
{
244
 while(timer--)
245
  {
51 holgerb 246
//   if(SENSE_H) { PORTC |= ROT; } else { PORTC &= ~ROT;}
50 holgerb 247
  }
248
 return(0);  
249
}
250
 
58 hbuss 251
/*
51 holgerb 252
void ShowSense(void)
253
{
254
 if(SENSE_H) { PORTC |= ROT; } else { PORTC &= ~ROT;}
50 holgerb 255
 
51 holgerb 256
}
58 hbuss 257
*/
51 holgerb 258
#define HIGH_A_EIN PORTB |= 0x08
259
#define HIGH_B_EIN PORTB |= 0x04
260
#define HIGH_C_EIN PORTB |= 0x02
261
#define LOW_A_EIN  PORTD |= 0x08
262
#define LOW_B_EIN  PORTD |= 0x10
263
#define LOW_C_EIN  PORTD |= 0x20
264
 
50 holgerb 265
void MotorTon(void)
1 ingob 266
//############################################################################
50 holgerb 267
{
51 holgerb 268
    unsigned char ADR_TAB[5] = {0,0,2,1,3};
50 holgerb 269
    unsigned int timer = 300,i;
51 holgerb 270
    unsigned int t = 0;
58 hbuss 271
    unsigned char anz = 0,MosfetOkay = 0, grenze = 50;
51 holgerb 272
 
273
    PORTC &= ~ROT;
274
    Delay_ms(300 * ADR_TAB[MotorAdresse]);    
50 holgerb 275
    DISABLE_SENSE_INT;
276
    cli();//Globale Interrupts Ausschalten
277
    uart_putchar('\n');
278
    STEUER_OFF;
58 hbuss 279
    Strom_max = 0;
280
    DelayM(50);
281
    RuheStrom = Strom_max;
282
//    uart_putchar(RuheStrom + 'A');
50 holgerb 283
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
284
//+ High-Mosfets auf Kurzschluss testen
285
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
286
    Strom = 0;
71 hbuss 287
/*
51 holgerb 288
    LOW_B_EIN;
289
    HIGH_A_EIN;
50 holgerb 290
    if(DelayM(3))
291
       {
292
        anz = 1;
51 holgerb 293
        uart_putchar('1');
50 holgerb 294
       }
51 holgerb 295
    FETS_OFF;
296
    Delay(1000);
50 holgerb 297
    Strom = 0;
51 holgerb 298
    LOW_A_EIN;
299
    HIGH_B_EIN;
50 holgerb 300
    if(DelayM(3))
301
       {
302
        anz = 2;
51 holgerb 303
        uart_putchar('2');
50 holgerb 304
       }
51 holgerb 305
    FETS_OFF;
306
    Delay(1000);
50 holgerb 307
    Strom = 0;
51 holgerb 308
    LOW_B_EIN; // Low C ein
309
    HIGH_C_EIN; // High B ein
50 holgerb 310
    if(DelayM(3))
311
       {
312
        anz = 3;
51 holgerb 313
        uart_putchar('3');
50 holgerb 314
       }
51 holgerb 315
    FETS_OFF;
316
    Delay(1000);
317
    LOW_A_EIN; // Low  A ein; und A gegen C
318
    HIGH_C_EIN; // High C ein
50 holgerb 319
    if(DelayM(3))
320
       {
321
        anz = 3;
51 holgerb 322
        uart_putchar('7');
50 holgerb 323
       }
51 holgerb 324
    FETS_OFF;
325
    DelayM(10000);
71 hbuss 326
 
51 holgerb 327
if(anz) while(1) RotBlink(anz);  // bei Kurzschluss nicht starten
71 hbuss 328
*/
50 holgerb 329
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
51 holgerb 330
//+ LOW-Mosfets auf Schalten und Kurzschluss testen
50 holgerb 331
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58 hbuss 332
 if(UDR == ' ') {t = 65535; grenze = 40; uart_putchar('_');} else t = 1000; // Ausführlicher Test
51 holgerb 333
 Strom = 0;
334
 for(i=0;i<t;i++)
335
 {
336
  LOW_A_EIN;
337
  DelayM(1);
338
  FETS_OFF;
339
  Delay(5);
340
  HIGH_A_EIN;
341
  DelayM(1);
342
  FETS_OFF;
73 hbuss 343
  if(Strom > grenze + RuheStrom) {anz = 4; uart_putchar('4'); FETS_OFF; break;}
51 holgerb 344
  Delay(5);
345
 }
346
 Delay(10000);
50 holgerb 347
 
51 holgerb 348
 Strom = 0;
349
 for(i=0;i<t;i++)
350
 {
351
  LOW_B_EIN;
352
  DelayM(1);
353
  FETS_OFF;
354
  Delay(5);
355
  HIGH_B_EIN;
356
  DelayM(1);
357
  FETS_OFF;
73 hbuss 358
  if(Strom > grenze + RuheStrom) {anz = 5; uart_putchar('5'); FETS_OFF;break;}
51 holgerb 359
  Delay(5);
360
 }
50 holgerb 361
 
51 holgerb 362
 Strom = 0;
363
 Delay(10000);
364
 
365
 for(i=0;i<t;i++)
366
 {
367
  LOW_C_EIN;
368
  DelayM(1);
369
  FETS_OFF;
370
  Delay(5);
371
  HIGH_C_EIN;
372
  DelayM(1);
373
  FETS_OFF;
73 hbuss 374
  if(Strom > grenze + RuheStrom) {anz = 6; uart_putchar('6'); FETS_OFF; break;}
51 holgerb 375
  Delay(5);
376
 }
377
 
73 hbuss 378
 if(anz) while(1) RotBlink(anz);  // bei Kurzschluss nicht starten
379
 
50 holgerb 380
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
381
//+ High-Mosfets auf Schalten testen
382
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
383
    SENSE_A;
51 holgerb 384
    FETS_OFF;
385
    LOW_B_EIN; // Low B ein
386
    LOW_C_EIN; // Low C ein
50 holgerb 387
    Strom = 0;
51 holgerb 388
#define TONDAUER  40000    
71 hbuss 389
#define SOUND_E 1  // 1
51 holgerb 390
#define SOUND1_A 300
391
#define SOUND2_A 330
392
#define SOUND3_A 360
393
 
50 holgerb 394
    for(i=0; i< (TONDAUER / SOUND2_A) ; i++)
395
     {
51 holgerb 396
      HIGH_A_EIN; // Test A
50 holgerb 397
      Delay(SOUND_E);
51 holgerb 398
      if(MessAD(0) > 50) { MosfetOkay |= 0x01; } else { MosfetOkay &= ~0x01;};
50 holgerb 399
      PORTB = 0;
51 holgerb 400
      Delay(SOUND1_A);
50 holgerb 401
     }
51 holgerb 402
    FETS_OFF;
403
 
404
    LOW_A_EIN; // Low A ein
405
    LOW_C_EIN; // Low C ein
50 holgerb 406
    for(i=0; i<(TONDAUER / SOUND1_A); i++)
407
     {
51 holgerb 408
      HIGH_B_EIN; // Test B
50 holgerb 409
      Delay(SOUND_E);
51 holgerb 410
      if(MessAD(1) > 50) { MosfetOkay |= 0x02; } else { MosfetOkay &= ~0x02;};
50 holgerb 411
      PORTB = 0;
412
      Delay(SOUND1_A);
413
     }
414
 
51 holgerb 415
    FETS_OFF;
416
    LOW_A_EIN; // Low A ein
417
    LOW_B_EIN; // Low B ein
50 holgerb 418
    for(i=0; i<(TONDAUER / SOUND3_A); i++)
419
     {
51 holgerb 420
      HIGH_C_EIN; // Test C
50 holgerb 421
      Delay(SOUND_E);
51 holgerb 422
      if(MessAD(2) > 50) { MosfetOkay |= 0x04; } else { MosfetOkay &= ~0x04;};
50 holgerb 423
      PORTB = 0;
51 holgerb 424
      Delay(SOUND2_A);
50 holgerb 425
     }
51 holgerb 426
    FETS_OFF;
50 holgerb 427
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
428
//+ Low-Mosfets auf Schalten testen
429
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
76 hbuss 430
//    SENSE_B;
51 holgerb 431
    LOW_A_EIN; // Low A ein
50 holgerb 432
    for(i=0; i< (TONDAUER / SOUND2_A) ; i++)
433
     {
51 holgerb 434
      HIGH_B_EIN; // Test B
50 holgerb 435
      Delay(SOUND_E);
76 hbuss 436
      if(MessAD(0) > 128) { MosfetOkay &= ~0x08;} else { MosfetOkay |= 0x08;};
50 holgerb 437
      PORTB = 0;
438
      Delay(SOUND2_A);
439
     }
51 holgerb 440
 
441
//++++++++++++++++++++++++++++++++++++
442
    LOW_C_EIN; // Low C ein
443
    for(i=0; i<(TONDAUER / SOUND1_A); i++)
50 holgerb 444
     {
51 holgerb 445
      HIGH_B_EIN; // Test B
50 holgerb 446
      Delay(SOUND_E);
76 hbuss 447
      if(MessAD(2) > 128) { MosfetOkay &= ~0x20;} else { MosfetOkay |= 0x20;};
50 holgerb 448
      PORTB = 0;
449
      Delay(SOUND3_A);
450
     }
51 holgerb 451
    FETS_OFF;
452
//++++++++++++++++++++++++++++++++++++
453
    FETS_OFF;
454
    LOW_B_EIN; // Low B ein
455
    for(i=0; i<(TONDAUER / SOUND3_A); i++)
50 holgerb 456
     {
51 holgerb 457
      HIGH_C_EIN; // Test C
50 holgerb 458
      Delay(SOUND_E);
76 hbuss 459
      if(MessAD(1) > 128) { MosfetOkay &= ~0x10;} else { MosfetOkay |= 0x10;};
50 holgerb 460
      PORTB = 0;
51 holgerb 461
      Delay(SOUND3_A);
50 holgerb 462
     }
51 holgerb 463
    FETS_OFF;
464
//++++++++++++++++++++++++++++++++++++
50 holgerb 465
 
51 holgerb 466
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
50 holgerb 467
    sei();//Globale Interrupts Einschalten
51 holgerb 468
//    Delay_ms(250 * MotorAdresse);    
469
/*
470
    LOW_A_EIN; // Low B ein
50 holgerb 471
#define SOUND8_A 650
472
    for(i=0; i<(TONDAUER / SOUND8_A); i++)
473
     {
51 holgerb 474
      HIGH_B_EIN; // Test B
475
      Delay(SOUND_E);
476
      PORTB = 0;
477
      Delay(SOUND8_A);
50 holgerb 478
     }
51 holgerb 479
*/
480
 Delay_ms(300 * (4-ADR_TAB[MotorAdresse]));    
58 hbuss 481
 if(!(MosfetOkay & 0x01))  { anz = 1; UDR='A'; } else
482
 if(!(MosfetOkay & 0x02))  { anz = 2; UDR='B'; } else
483
 if(!(MosfetOkay & 0x04))  { anz = 3; UDR='C'; } else
484
 if(!(MosfetOkay & 0x08))  { anz = 4; UDR='a'; } else
485
 if(!(MosfetOkay & 0x10))  { anz = 5; UDR='b'; } else
486
 if(!(MosfetOkay & 0x20))  { anz = 6; UDR='c'; }  
50 holgerb 487
 
73 hbuss 488
// if(anz) Delay_ms(1000); 
489
 if(anz) while(1) RotBlink(anz);  // bei Kurzschluss nicht starten
51 holgerb 490
 RotBlink(anz);
491
 uart_putchar('.');
50 holgerb 492
}
493
 
494
//############################################################################
1 ingob 495
//
496
unsigned char SollwertErmittlung(void)
497
//############################################################################
498
{
499
    static unsigned int sollwert = 0;
500
    unsigned int ppm;
501
    if(!I2C_Timeout)   // bei Erreichen von 0 ist der Wert ungültig
502
        {
503
        if(SIO_Timeout)  // es gibt gültige SIO-Daten
504
            {
50 holgerb 505
             sollwert =  (MAX_PWM * (unsigned int) SIO_Sollwert) / 200;  // skalieren auf 0-200 = 0-255
506
             PPM_Betrieb = 0;
507
             ICP_INT_DISABLE;
508
             PORTC &= ~ROT;
1 ingob 509
            }
510
        else
50 holgerb 511
            if(anz_ppm_werte > 20)  // es gibt gültige PPM-Daten
1 ingob 512
                {
50 holgerb 513
                PPM_Betrieb = 1;
1 ingob 514
                ppm = PPM_Signal;
515
                if(ppm > 300) ppm =   0;  // ungültiges Signal
516
                if(ppm > 200) ppm = 200;
517
                if(ppm <= MIN_PPM) sollwert = 0;
518
                else
519
                    {
520
                    sollwert = (int) MIN_PWM + ((MAX_PWM - MIN_PWM) * (ppm - MIN_PPM)) / (190 - MIN_PPM);
521
                    }
522
                PORTC &= ~ROT;
523
                }
524
            else   // Kein gültiger Sollwert
525
                {
50 holgerb 526
                 if(!TEST_SCHUB) { if(sollwert) sollwert--; }  
527
                 PORTC |= ROT;
1 ingob 528
                }
529
        }
530
    else // I2C-Daten sind gültig
531
        {
532
        sollwert = I2C_RXBuffer;
50 holgerb 533
        PPM_Betrieb = 0;
1 ingob 534
        PORTC &= ~ROT;
50 holgerb 535
        ICP_INT_DISABLE;
1 ingob 536
        }
537
    if(sollwert > MAX_PWM) sollwert = MAX_PWM;
538
    return(sollwert);
539
}
540
 
541
 
542
 
543
//############################################################################
544
//Hauptprogramm
545
int main (void)
546
//############################################################################
547
{
548
    char altPhase = 0;
549
    int test = 0;
73 hbuss 550
    unsigned int Blink,TestschubTimer;
1 ingob 551
    unsigned int Blink2,MittelstromTimer,DrehzahlMessTimer,MotorGestopptTimer;
552
 
553
    DDRC  = 0x08;
554
    PORTC = 0x08;
73 hbuss 555
    DDRD  = 0x3A;
26 ingob 556
    PORTD = 0x00;
1 ingob 557
    DDRB  = 0x0E;
558
    PORTB = 0x31;
24 ingob 559
 
560
#if (MOTORADRESSE == 0)
561
    PORTB |= (ADR1 + ADR2);   // Pullups für Adresswahl
43 holgerb 562
    for(test=0;test<500;test++);
73 hbuss 563
    if(PINB & ADR1)
24 ingob 564
         {
565
           if (PINB & ADR2) MotorAdresse = 1;
566
            else MotorAdresse = 2;
567
         }
568
         else
569
         {
570
           if (PINB & ADR2) MotorAdresse = 3;
571
            else MotorAdresse = 4;
572
         }
73 hbuss 573
    HwVersion = 11;
24 ingob 574
#else
575
    MotorAdresse  = MOTORADRESSE;
73 hbuss 576
    HwVersion = 10;
24 ingob 577
#endif
73 hbuss 578
    if(PIND & 0x80) {HwVersion = 12; IntRef = 0xc0;}    
579
    DDRD  = 0xBA;
1 ingob 580
    UART_Init();
581
    Timer0_Init();
50 holgerb 582
    sei();//Globale Interrupts Einschalten
1 ingob 583
 
584
    // Am Blinken erkennt man die richtige Motoradresse
50 holgerb 585
/*
1 ingob 586
    for(test=0;test<5;test++)
587
        {
24 ingob 588
        if(test == MotorAdresse) PORTD |= GRUEN;
1 ingob 589
        Delay_ms(150);
590
        PORTD &= ~GRUEN;
591
        Delay_ms(250);
592
        }      
593
 
594
    Delay_ms(500);
50 holgerb 595
*/  
18 ingob 596
   // UART_Init();  // war doppelt
1 ingob 597
    PWM_Init();
598
 
599
    InitIC2_Slave(0x50);                           
600
    InitPPM();
601
 
602
    Blink             = SetDelay(101);    
603
    Blink2            = SetDelay(102);
604
    MinUpmPulse       = SetDelay(103);
605
    MittelstromTimer  = SetDelay(254);
606
    DrehzahlMessTimer = SetDelay(1005);
607
    TestschubTimer    = SetDelay(1006);
50 holgerb 608
    while(!CheckDelay(MinUpmPulse))
609
    {
610
     if(SollwertErmittlung()) break;
611
    }
73 hbuss 612
 
613
    GRN_ON;
1 ingob 614
    PWM = 0;
615
 
616
    SetPWM();
617
 
618
    SFIOR = 0x08;  // Analog Comperator ein
619
    ADMUX = 1;
620
 
621
    MinUpmPulse = SetDelay(10);
622
    DebugOut.Analog[1] = 1;
623
    PPM_Signal = 0;
624
 
50 holgerb 625
    if(!SollwertErmittlung()) MotorTon();
58 hbuss 626
//MotorTon();    
627
    PORTB = 0x31; // Pullups wieder einschalten
50 holgerb 628
 
1 ingob 629
    // zum Test der Hardware; Motor dreht mit konstanter Drehzahl ohne Regelung
630
    if(TEST_MANUELL)    Anwerfen(TEST_MANUELL);  // kommt von dort nicht wieder
631
 
632
    while (1)
633
        {
51 holgerb 634
//ShowSense();
635
 
1 ingob 636
        if(!TEST_SCHUB)   PWM = SollwertErmittlung();
637
        //I2C_TXBuffer = PWM; // Antwort über I2C-Bus
638
        if(MANUELL_PWM)   PWM = MANUELL_PWM;
639
 
640
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
641
        if(Phase != altPhase)   // es gab eine Kommutierung im Interrupt
642
            {
643
            MotorGestoppt = 0;
644
            ZeitFuerBerechnungen = 0;    // direkt nach einer Kommutierung ist Zeit 
58 hbuss 645
            MinUpmPulse = SetDelay(250);  // Timeout, falls ein Motor stehen bleibt
1 ingob 646
            altPhase = Phase;
647
            }
648
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
649
        if(!PWM)    // Sollwert == 0
650
            {
651
            MotorAnwerfen = 0;      // kein Startversuch
652
            ZeitFuerBerechnungen = 0;
653
            // nach 1,5 Sekunden den Motor als gestoppt betrachten 
18 ingob 654
            if(CheckDelay(MotorGestopptTimer))
1 ingob 655
                {
656
                DISABLE_SENSE_INT;
657
                MotorGestoppt = 1;  
658
                STEUER_OFF;
659
                }
660
            }
661
        else
662
            {
663
            if(MotorGestoppt) MotorAnwerfen = 1;        // Startversuch
664
            MotorGestopptTimer = SetDelay(1500);
665
            }
666
 
667
        if(MotorGestoppt && !TEST_SCHUB) PWM = 0;
668
        SetPWM();
669
        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
670
        if(!ZeitFuerBerechnungen++)
671
            {
73 hbuss 672
            if(MotorGestoppt)
673
             {
674
              GRN_ON;
675
              FastADConvert();
676
             }
1 ingob 677
            if(SIO_DEBUG)
678
                {
679
                DebugAusgaben();  // welche Werte sollen angezeigt werden?
680
                if(!UebertragungAbgeschlossen)  SendUart();
681
                else DatenUebertragung();
682
                }
683
            // Berechnen des Mittleren Stroms zur (langsamen) Strombegrenzung
684
            if(CheckDelay(MittelstromTimer))  
685
                {
686
                MittelstromTimer = SetDelay(50); // alle 50ms
687
                if(Mittelstrom <  Strom) Mittelstrom++;// Mittelwert des Stroms bilden
688
                else if(Mittelstrom >  Strom) Mittelstrom--;
73 hbuss 689
                if(Strom > MAX_STROM) MaxPWM -= MaxPWM / 32;              
58 hbuss 690
                if((Mittelstrom > LIMIT_STROM))// Strom am Limit?
1 ingob 691
                    {
58 hbuss 692
                    if(MaxPWM) MaxPWM--;// dann die Maximale PWM herunterfahren
1 ingob 693
                    PORTC |= ROT;
694
                    }
695
                else
696
                    {
697
                    if(MaxPWM < MAX_PWM) MaxPWM++;
698
                    }
699
                }
700
 
701
            if(CheckDelay(DrehzahlMessTimer))   // Ist-Drehzahl bestimmen
702
                {
703
                DrehzahlMessTimer = SetDelay(10);
58 hbuss 704
                SIO_Drehzahl = CntKommutierungen;//(6 * CntKommutierungen) / (POLANZAHL / 2);
1 ingob 705
                CntKommutierungen = 0;
71 hbuss 706
               // if(PPM_Timeout == 0) // keine PPM-Signale
1 ingob 707
                ZeitZumAdWandeln = 1;
708
                }
73 hbuss 709
 
710
#if TEST_SCHUB == 1
58 hbuss 711
           {
1 ingob 712
            if(CheckDelay(TestschubTimer))  
713
                {
714
                TestschubTimer = SetDelay(1500);
715
                    switch(test)
716
                        {
717
                        case 0: PWM = 50; test++; break;
718
                        case 1: PWM = 130; test++; break;
719
                        case 2: PWM = 60;  test++; break;
720
                        case 3: PWM = 140; test++; break;
721
                        case 4: PWM = 150; test = 0; break;
722
                        default: test = 0;
723
                        }
724
                }
58 hbuss 725
            }  
73 hbuss 726
#endif
58 hbuss 727
          // Motor Stehen geblieben
1 ingob 728
            if((CheckDelay(MinUpmPulse) && SIO_Drehzahl == 0) || MotorAnwerfen)
729
                {
730
                MotorGestoppt = 1;    
731
                DISABLE_SENSE_INT;
732
                MinUpmPulse = SetDelay(100);        
733
                if(MotorAnwerfen)
73 hbuss 734
                  {
735
                   PORTC &= ~ROT;
736
                   Strom_max = 0;
737
                   MotorAnwerfen = 0;
738
                   if(Anwerfen(10))
739
                   {  
740
                    GRN_ON;
1 ingob 741
                    MotorGestoppt = 0;    
742
                    Phase--;
743
                    PWM = 1;
744
                    SetPWM();
745
                    SENSE_TOGGLE_INT;
746
                    ENABLE_SENSE_INT;
73 hbuss 747
                    MinUpmPulse = SetDelay(20);
1 ingob 748
                    while(!CheckDelay(MinUpmPulse)); // kurz Synchronisieren
43 holgerb 749
                    PWM = 15;
1 ingob 750
                    SetPWM();
43 holgerb 751
                    MinUpmPulse = SetDelay(300);
73 hbuss 752
                    while(!CheckDelay(MinUpmPulse)) // kurz Durchstarten
753
                    {
754
                      if(Strom > LIMIT_STROM/2)
755
                      {
756
                        STEUER_OFF; // Abschalten wegen Kurzschluss
757
                        RotBlink(10);
758
                        MotorAnwerfen = 1;
759
                      }  
760
                    }
18 ingob 761
                                    // Drehzahlmessung wieder aufsetzen
762
                    DrehzahlMessTimer = SetDelay(50);
1 ingob 763
                    altPhase = 7;
73 hbuss 764
                   }
765
                   else if(SollwertErmittlung()) MotorAnwerfen = 1;
766
                  }
1 ingob 767
                }
768
            } // ZeitFuerBerechnungen
769
        } // while(1) - Hauptschleife
770
}
771