Subversion Repositories BL-Ctrl

Rev

Rev 90 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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