Forum: Compiler & IDEs Ist mein µC schnell genug?


von Alex H. (sherlock)


Lesenswert?

Hallo Leute!



Ich bin dabei einen Code für einen BLDC Motor Treiber zu schreiben.
Der Code ist noch nicht ganz fertig und wenn ich auf build klicke, zeigt 
mir das Programm folgendes:

Program Memory Usage   :  6910 bytes   21,1 % Full

Speicher ist zwar noch genügend da, aber bei einem Motor Treiber ist 
genaues Timing ja sehr wichtig.

Wie finde ich heraus ob mein ATmega32 schnell genug für den Code ist, 
oder muss ich mir da keine sogen machen solange der Programm Speicher 
nicht voll ist?

von Henning (Gast)


Lesenswert?

Die Codegröße hat doch rein gar nichts mit der Geschwindigkeit zu tun.

von Alex H. (sherlock)


Lesenswert?

Das habe ich mir gedacht, aber wie finde ich das dann raus?

von Andreas B. (bitverdreher)


Lesenswert?

Indem Du das ausprobierst.
Ansonsten: wenn  Du mehr Infos rausrückst (Code), kann man das 
vielleicht abschätzen.

Gruß
Andreas

von Stefan P. (form)


Lesenswert?

Setz im Programm an den Stellen wo nichts getan wird ein Pin auf High 
und schau Dir das Puls/Pausen-Verhälntnis auf einem Oszi an. Damit 
kannst Du deine µC-Load von 0..100% ausrechnen.

von Frank (Gast)


Lesenswert?

Das hängt von Deinem Programm ab. Wie schnell muß an den IO-Ports 
gewackelt werden? Wie schnell muß der µC auf Interrupts reagieren bzw. 
was muß er in welcher Zeit erledigen? Da gibt es keine pauschale 
Antwort. Wie Henning schon gesagt hat, mit der Programmgröße hat das 
überhaupt nix zu tun.

Frank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Alex H. schrieb:
> Das habe ich mir gedacht, aber wie finde ich das dann raus?

LSS-Datei anschauen, im Datenblatt nachsehen, wieviel Takte welcher 
Befehl verbraucht, die Takte addieren und dann mittels F_CPU in eine 
Zeit umrechnen.

von Mike (Gast)


Lesenswert?

>Wie finde ich heraus ob mein ATmega32
Also normalerweise macht das ein AVR mit links! (Optimierung beim 
Compilieren einschalten!)

Wieviele MHz hat dein AVR und wievile kHz braucht dein Motor?

von Tobias L. (murxwitz)


Lesenswert?

messen?
pinwackeln (an passender Stelle im Programm zb Anfang main()) und die 
Frequenz messen

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Stefan P. schrieb:
> Setz im Programm an den Stellen wo nichts getan wird ein Pin auf High
> und schau Dir das Puls/Pausen-Verhälntnis auf einem Oszi an. Damit
> kannst Du deine µC-Load von 0..100% ausrechnen.

Ich glaube, er will nicht die CPU-Last wissen, sondern wieviel Zeit 
bestimmte Teile seines Programms benötigen.

von Alex H. (sherlock)


Lesenswert?

Achso Danke, ich werde erstmal das mit dem Pinwackeln ausprobieren, das 
hört sich am Einfachsten an :)

von kopfkratzer (Gast)


Lesenswert?

kopfkratz
Wenn man ja wissen würde wie schnell Dein µC getaktet ist, 1MHz intern 
oder 20MHz extern ?
Was soll Dein Programm tun, eine Rampe für den Motor abbilden ?
Glaskugelbestell

von Alex H. (sherlock)


Lesenswert?

start.h:
1
/*
2
 * start.h
3
 *
4
 * Created: 26.09.2013 08:55:17
5
 *  Author: Alex
6
 */ 
7
8
9
#include <avr/io.h>
10
#include <avr/interrupt.h>
11
#include <math.h>
12
13
14
#ifndef F_CPU
15
#define F_CPU           1000000UL //1MHZ
16
#endif
17
18
19
#ifndef START_H_
20
#define START_H_
21
22
23
24
25
26
#endif /* START_H_ */
27
28
29
30
31
32
33
34
35
36
struct Treiber
37
{
38
  public:
39
  
40
  uint16_t      Anlauf      ( uint16_t drehzahl_soll );
41
  void        Steps      ( unsigned int anlauf_step, unsigned int interrupt_step, uint8_t pPWM, unsigned int U_interr );
42
  short        PWM        ( uint8_t vPWM );
43
  signed long long  TSEC_ber    ( unsigned int degree_ist, unsigned int Umin_soll, unsigned int Umin, unsigned long long t_U );
44
  unsigned int    Umin_ber    ( unsigned int winkel1 );
45
  unsigned long long  TimeU      ( unsigned int winkel2 );
46
  unsigned int    Time_toStep    ( signed long long StepTime, unsigned int BEMFwinkel );
47
  
48
49
  
50
  
51
  
52
  private:
53
  
54
55
  uint8_t vPWMc;
56
  
57
  
58
  
59
  unsigned long long  t_seq;
60
  unsigned int    degree_max;
61
  unsigned int    Umin_max;
62
  signed int      degree;
63
  unsigned long long  time;
64
  unsigned int    U;
65
  unsigned int    Uret;
66
  unsigned long long  time2;
67
  unsigned long long  time_ret;
68
  unsigned char    ii;  
69
  unsigned char    iii;
70
  unsigned char    stepAnlauf;
71
  unsigned char    go;
72
  unsigned long long  changeTime;
73
  unsigned long long  cTime;
74
  unsigned int    step;
75
  
76
  unsigned int sStep;
77
  
78
  
79
  
80
  unsigned long long W30;
81
  unsigned int stop1;
82
  signed long long StepTime1;
83
  unsigned long long StepTimer1;
84
  
85
  unsigned long long W90;
86
  unsigned int stop2;
87
  signed long long StepTime2;
88
  unsigned long long StepTimer2;
89
  
90
  unsigned long long W150;
91
  unsigned int stop3;
92
  signed long long StepTime3;
93
  unsigned long long StepTimer3;
94
  
95
  unsigned long long W210;
96
  unsigned int stop4;
97
  signed long long StepTime4;
98
  unsigned long long StepTimer4;
99
        
100
  unsigned long long W270;
101
  unsigned int stop5;
102
  signed long long StepTime5;
103
  unsigned long long StepTimer5;
104
  
105
  unsigned long long W330;
106
  unsigned int stop6;
107
  signed long long StepTime6;
108
  unsigned long long StepTimer6;
109
  
110
};



work.cpp
1
/*
2
 * work.cpp
3
 *
4
 * Created: 26.09.2013 09:00:33
5
 *  Author: Alex
6
 */ 
7
8
9
10
#include "start.h"
11
12
13
14
15
#define    phase1m              PC0
16
#define    phase1p              PC1
17
#define    phase2m              PC2
18
#define    phase2p              PC3
19
#define    phase3m              PC4
20
#define    phase3p              PC5
21
#define    maxWinkelBEMF          60
22
#define    maxDrehzahlUnterschied      50
23
24
25
26
27
28
29
30
uint16_t Treiber::Anlauf(uint16_t drehzahl_soll )
31
{
32
  uint16_t drehzahl_ist;
33
34
  
35
  if (drehzahl_ist<drehzahl_soll  )
36
  {
37
    drehzahl_ist += 1;
38
  }
39
  changeTime = 1/(drehzahl_ist/60)*1000000;
40
  
41
  cTime++;
42
  if(cTime > changeTime)
43
  {
44
    stepAnlauf++;
45
    cTime = 0;
46
  }  
47
  if(stepAnlauf == 6)
48
  {
49
    stepAnlauf == 0;
50
  }
51
  
52
  return stepAnlauf;
53
}
54
55
56
void Treiber::Steps(unsigned int anlauf_step, unsigned int interrupt_step, uint8_t pPWM, unsigned int U_interr)
57
{
58
59
  if(U_interr == 0)
60
  {
61
    step = anlauf_step;
62
  }
63
  else
64
  {
65
    step = interrupt_step;
66
  }
67
68
  if ( step == 0 && pPWM == 1 )
69
  {
70
    PORTC &=   ~( (1<<phase1m)  |  (1<<phase2p)  |  (1<<phase3p)  |  (1<<phase2m) );
71
    PORTC |=    ( (1<<phase1p)  |  (1<<phase3m) );
72
    MCUCR &=  ~(  1<<ISC00 );    
73
  }    
74
75
76
  if ( step == 1 && pPWM == 1 )
77
  {
78
    PORTC &=   ~( (1<<phase1m)  |  (1<<phase2p)  |  (1<<phase3p)  |  (1<<phase3m) );
79
    PORTC |=    ( (1<<phase1p)  |  (1<<phase2m) );
80
    MCUCR |=   (  1<<ISC10 );
81
  }
82
83
84
85
  if ( step == 2 && pPWM == 1 )
86
  {
87
    PORTC &=   ~( (1<<phase1m)  |  (1<<phase2p)  |  (1<<phase1p)  |  (1<<phase3m) );
88
    PORTC |=    ( (1<<phase3p)  |  (1<<phase2m) );
89
    MCUCSR &=   ~(1<<ISC2);
90
  }
91
92
93
94
  if ( step == 3 && pPWM == 1 )
95
  {
96
97
    PORTC &=   ~( (1<<phase1p)  |  (1<<phase2p)  |  (1<<phase2m)  |  (1<<phase3m) );
98
    PORTC |=    ( (1<<phase1m)  |  (1<<phase3p) );
99
    MCUCR |=   ( 1<<ISC00);
100
  }
101
102
103
  if ( step == 4 && pPWM == 1 )
104
  {
105
    PORTC &=   ~( (1<<phase1p)  |  (1<<phase2m)  |  (1<<phase3p)  |  (1<<phase3m) );
106
    PORTC |=    ( (1<<phase1m)  |  (1<<phase2p) );
107
    MCUCR &=  ~(1<<ISC10);
108
  }
109
110
111
112
  if ( step == 5 && pPWM == 1 )
113
  {
114
    PORTC &=   ~( (1<<phase1m)  |  (1<<phase2m)  |  (1<<phase3p)  |  (1<<phase1p) );
115
    PORTC |=    ( (1<<phase2p)  |  (1<<phase3m) );
116
    MCUCSR |=  ( 1<<ISC2);
117
  }
118
  
119
  
120
  if(pPWM == 0)
121
  {
122
    PORTC &=   ~( (1<<phase1m)  |  (1<<phase2p)  |  (1<<phase3m)  |  (1<<phase2m)  |  (1<<phase3p)  |  (1<<phase1p) );  
123
  }
124
125
}
126
127
128
short Treiber::PWM(uint8_t vPWM)
129
{
130
  vPWMc ++;
131
  if (vPWMc>=100)
132
  {
133
    vPWMc = 0;
134
  }
135
  if (vPWM>vPWMc)
136
  {
137
    return 1;
138
  }
139
  else
140
  {
141
    return 0;
142
  }
143
}
144
145
146
signed long long Treiber::TSEC_ber (unsigned int degree_ist, unsigned int Umin_soll, unsigned int Umin, unsigned long long t_U )
147
{
148
  if( (Umin_soll-Umin)/maxDrehzahlUnterschied*maxWinkelBEMF > maxWinkelBEMF ) // 50 maximaler Umin unterschied
149
  {
150
    degree = maxWinkelBEMF;
151
  }
152
  
153
  else if( (Umin_soll-Umin)/maxDrehzahlUnterschied*maxWinkelBEMF < -maxWinkelBEMF ) // 50 maximaler Umin unterschied
154
  {
155
    degree = -maxWinkelBEMF;
156
  }
157
  
158
  else
159
  {
160
    degree = (Umin_soll-Umin)/maxDrehzahlUnterschied*maxWinkelBEMF;  
161
  }
162
  
163
  return (degree_ist+degree)/degree_ist*t_U-t_U;
164
  
165
}
166
167
168
169
170
171
unsigned int Treiber::Umin_ber(unsigned int winkel1)
172
{
173
  time ++;
174
  
175
  
176
  if (time >= 1000000)
177
  {
178
    Uret = U;
179
    U = 0;
180
    time = 0;
181
  }
182
  
183
  if (winkel1 == 330 && ii == 0)
184
  {
185
    U++;
186
    ii = 1;
187
  }
188
  if( winkel1 != 330 && ii == 1 )
189
  {
190
    ii = 0; 
191
  }
192
  
193
  return Uret*60;
194
}
195
196
197
unsigned long long Treiber::TimeU(unsigned int winkel2)
198
{
199
  time2++;
200
201
  if( winkel2 == 330 && iii == 0)
202
  {
203
    time_ret = time2;
204
    time2=0;
205
    iii = 1;    
206
  }
207
  if( winkel2 != 330 && iii == 1)
208
  {
209
    iii = 0;
210
  }
211
  return time_ret; 
212
}
213
214
215
unsigned int Treiber::Time_toStep(signed long long StepTime, unsigned int BEMFwinkel )
216
{
217
  
218
219
220
221
  
222
  if( BEMFwinkel == 30 )
223
  {
224
    W30++;////////////
225
    if(stop1 == 0)
226
    {
227
      StepTime1 = StepTime; 
228
      stop1 = 1;    
229
    }
230
  }
231
  else
232
  {
233
    stop1 = 0;  
234
  }
235
  
236
237
  StepTimer1++;
238
  
239
  
240
  if( StepTimer1 >= StepTime1 + ( W330 * 1.5 ) )
241
  {
242
    sStep = 1;
243
    W330 = 0;/////////////////
244
    StepTimer1 = 0;      
245
  }
246
  
247
  
248
  
249
  
250
  
251
  
252
  
253
  
254
  
255
  if( BEMFwinkel == 90 )
256
  {
257
    W90++;////////////
258
    if(stop2 == 0)
259
    {
260
      StepTime2 = StepTime; 
261
      stop2 = 1;    
262
    }
263
  }
264
  else
265
  {
266
    stop2 = 0;  
267
  }
268
  
269
270
  StepTimer2++;
271
  
272
  
273
  if( StepTimer2 >= StepTime2 + ( W30 * 1.5 ) )
274
  {
275
    sStep = 2;
276
    W30 = 0;/////////////////
277
    StepTimer2 = 0;    
278
  }  
279
280
  
281
  
282
  
283
  
284
  
285
286
      
287
  if( BEMFwinkel == 150 )
288
  {
289
    W150++;////////////
290
    if(stop3 == 0)
291
    {
292
      StepTime3 = StepTime; 
293
      stop3 = 1;    
294
    }
295
  }
296
  else
297
  {
298
    stop3 = 0;  
299
  }
300
  
301
302
  StepTimer3++;
303
  
304
  
305
  if( StepTimer3 >= StepTime3 + ( W90 * 1.5 ) )
306
  {
307
    sStep = 3;
308
    W90 = 0;/////////////////
309
    StepTimer3 = 0;    
310
  }
311
  
312
  
313
  
314
  
315
  
316
  
317
  
318
  
319
  if( BEMFwinkel == 210 )
320
  {
321
    W210++;////////////
322
    if(stop4 == 0)
323
    {
324
      StepTime4 = StepTime; 
325
326
      stop4 = 1;    
327
    }
328
  }
329
  else
330
  {
331
    stop4 = 0;  
332
  }
333
  
334
335
  StepTimer4++;
336
  
337
  
338
  if( StepTimer4 >= StepTime4 + ( W150 * 1.5 ) )
339
  {
340
    sStep = 4;
341
    W150 = 0;/////////////////
342
    StepTimer4 = 0;    
343
  }  
344
  
345
  
346
  
347
  
348
  
349
  
350
351
  
352
  
353
  if( BEMFwinkel == 270 )
354
  {
355
    W270++;////////////
356
    if(stop5 == 0)
357
    {
358
      StepTime5 = StepTime; 
359
360
      stop5 = 1;    
361
    }
362
  }
363
  else
364
  {
365
    stop5 = 0;  
366
  }
367
  
368
369
  StepTimer5++;
370
  
371
  
372
  if( StepTimer5 >= StepTime5 + ( W210 * 1.5 ) )
373
  {
374
    sStep = 5;
375
    W210 = 0;/////////////////
376
    StepTimer5 = 0;  
377
  }
378
  
379
  
380
  
381
  
382
  
383
  
384
  
385
  
386
  
387
  if( BEMFwinkel == 330 )
388
  {
389
    W330++;////////////
390
    if(stop6 == 0)
391
    {
392
      StepTime6 = StepTime; 
393
      stop6 = 1;    
394
    }
395
  }
396
  else
397
  {
398
    stop6 = 0;  
399
  }
400
  
401
402
  StepTimer6++;
403
  
404
  
405
  if( StepTimer6 >= StepTime6 + ( W270 * 1.5 ) )
406
  {
407
    sStep = 0;
408
    W270 = 0;/////////////////
409
    StepTimer6 = 0;  
410
  }  
411
412
413
414
415
  return sStep;
416
}



BLDC_Driver.cpp
1
/*
2
 * work.cpp
3
 *
4
 * Created: 26.09.2013 09:00:33
5
 *  Author: Alex
6
 */ 
7
8
9
10
#include "start.h"
11
12
13
14
15
#define    phase1m              PC0
16
#define    phase1p              PC1
17
#define    phase2m              PC2
18
#define    phase2p              PC3
19
#define    phase3m              PC4
20
#define    phase3p              PC5
21
#define    maxWinkelBEMF          60
22
#define    maxDrehzahlUnterschied      50
23
24
25
26
27
28
29
30
uint16_t Treiber::Anlauf(uint16_t drehzahl_soll )
31
{
32
  uint16_t drehzahl_ist;
33
34
  
35
  if (drehzahl_ist<drehzahl_soll  )
36
  {
37
    drehzahl_ist += 1;
38
  }
39
  changeTime = 1/(drehzahl_ist/60)*1000000;
40
  
41
  cTime++;
42
  if(cTime > changeTime)
43
  {
44
    stepAnlauf++;
45
    cTime = 0;
46
  }  
47
  if(stepAnlauf == 6)
48
  {
49
    stepAnlauf == 0;
50
  }
51
  
52
  return stepAnlauf;
53
}
54
55
56
void Treiber::Steps(unsigned int anlauf_step, unsigned int interrupt_step, uint8_t pPWM, unsigned int U_interr)
57
{
58
59
  if(U_interr == 0)
60
  {
61
    step = anlauf_step;
62
  }
63
  else
64
  {
65
    step = interrupt_step;
66
  }
67
68
  if ( step == 0 && pPWM == 1 )
69
  {
70
    PORTC &=   ~( (1<<phase1m)  |  (1<<phase2p)  |  (1<<phase3p)  |  (1<<phase2m) );
71
    PORTC |=    ( (1<<phase1p)  |  (1<<phase3m) );
72
    MCUCR &=  ~(  1<<ISC00 );    
73
  }    
74
75
76
  if ( step == 1 && pPWM == 1 )
77
  {
78
    PORTC &=   ~( (1<<phase1m)  |  (1<<phase2p)  |  (1<<phase3p)  |  (1<<phase3m) );
79
    PORTC |=    ( (1<<phase1p)  |  (1<<phase2m) );
80
    MCUCR |=   (  1<<ISC10 );
81
  }
82
83
84
85
  if ( step == 2 && pPWM == 1 )
86
  {
87
    PORTC &=   ~( (1<<phase1m)  |  (1<<phase2p)  |  (1<<phase1p)  |  (1<<phase3m) );
88
    PORTC |=    ( (1<<phase3p)  |  (1<<phase2m) );
89
    MCUCSR &=   ~(1<<ISC2);
90
  }
91
92
93
94
  if ( step == 3 && pPWM == 1 )
95
  {
96
97
    PORTC &=   ~( (1<<phase1p)  |  (1<<phase2p)  |  (1<<phase2m)  |  (1<<phase3m) );
98
    PORTC |=    ( (1<<phase1m)  |  (1<<phase3p) );
99
    MCUCR |=   ( 1<<ISC00);
100
  }
101
102
103
  if ( step == 4 && pPWM == 1 )
104
  {
105
    PORTC &=   ~( (1<<phase1p)  |  (1<<phase2m)  |  (1<<phase3p)  |  (1<<phase3m) );
106
    PORTC |=    ( (1<<phase1m)  |  (1<<phase2p) );
107
    MCUCR &=  ~(1<<ISC10);
108
  }
109
110
111
112
  if ( step == 5 && pPWM == 1 )
113
  {
114
    PORTC &=   ~( (1<<phase1m)  |  (1<<phase2m)  |  (1<<phase3p)  |  (1<<phase1p) );
115
    PORTC |=    ( (1<<phase2p)  |  (1<<phase3m) );
116
    MCUCSR |=  ( 1<<ISC2);
117
  }
118
  
119
  
120
  if(pPWM == 0)
121
  {
122
    PORTC &=   ~( (1<<phase1m)  |  (1<<phase2p)  |  (1<<phase3m)  |  (1<<phase2m)  |  (1<<phase3p)  |  (1<<phase1p) );  
123
  }
124
125
}
126
127
128
short Treiber::PWM(uint8_t vPWM)
129
{
130
  vPWMc ++;
131
  if (vPWMc>=100)
132
  {
133
    vPWMc = 0;
134
  }
135
  if (vPWM>vPWMc)
136
  {
137
    return 1;
138
  }
139
  else
140
  {
141
    return 0;
142
  }
143
}
144
145
146
signed long long Treiber::TSEC_ber (unsigned int degree_ist, unsigned int Umin_soll, unsigned int Umin, unsigned long long t_U )
147
{
148
  if( (Umin_soll-Umin)/maxDrehzahlUnterschied*maxWinkelBEMF > maxWinkelBEMF ) // 50 maximaler Umin unterschied
149
  {
150
    degree = maxWinkelBEMF;
151
  }
152
  
153
  else if( (Umin_soll-Umin)/maxDrehzahlUnterschied*maxWinkelBEMF < -maxWinkelBEMF ) // 50 maximaler Umin unterschied
154
  {
155
    degree = -maxWinkelBEMF;
156
  }
157
  
158
  else
159
  {
160
    degree = (Umin_soll-Umin)/maxDrehzahlUnterschied*maxWinkelBEMF;  
161
  }
162
  
163
  return (degree_ist+degree)/degree_ist*t_U-t_U;
164
  
165
}
166
167
168
169
170
171
unsigned int Treiber::Umin_ber(unsigned int winkel1)
172
{
173
  time ++;
174
  
175
  
176
  if (time >= 1000000)
177
  {
178
    Uret = U;
179
    U = 0;
180
    time = 0;
181
  }
182
  
183
  if (winkel1 == 330 && ii == 0)
184
  {
185
    U++;
186
    ii = 1;
187
  }
188
  if( winkel1 != 330 && ii == 1 )
189
  {
190
    ii = 0; 
191
  }
192
  
193
  return Uret*60;
194
}
195
196
197
unsigned long long Treiber::TimeU(unsigned int winkel2)
198
{
199
  time2++;
200
201
  if( winkel2 == 330 && iii == 0)
202
  {
203
    time_ret = time2;
204
    time2=0;
205
    iii = 1;    
206
  }
207
  if( winkel2 != 330 && iii == 1)
208
  {
209
    iii = 0;
210
  }
211
  return time_ret; 
212
}
213
214
215
unsigned int Treiber::Time_toStep(signed long long StepTime, unsigned int BEMFwinkel )
216
{
217
  
218
219
220
221
  
222
  if( BEMFwinkel == 30 )
223
  {
224
    W30++;////////////
225
    if(stop1 == 0)
226
    {
227
      StepTime1 = StepTime; 
228
      stop1 = 1;    
229
    }
230
  }
231
  else
232
  {
233
    stop1 = 0;  
234
  }
235
  
236
237
  StepTimer1++;
238
  
239
  
240
  if( StepTimer1 >= StepTime1 + ( W330 * 1.5 ) )
241
  {
242
    sStep = 1;
243
    W330 = 0;/////////////////
244
    StepTimer1 = 0;      
245
  }
246
  
247
  
248
  
249
  
250
  
251
  
252
  
253
  
254
  
255
  if( BEMFwinkel == 90 )
256
  {
257
    W90++;////////////
258
    if(stop2 == 0)
259
    {
260
      StepTime2 = StepTime; 
261
      stop2 = 1;    
262
    }
263
  }
264
  else
265
  {
266
    stop2 = 0;  
267
  }
268
  
269
270
  StepTimer2++;
271
  
272
  
273
  if( StepTimer2 >= StepTime2 + ( W30 * 1.5 ) )
274
  {
275
    sStep = 2;
276
    W30 = 0;/////////////////
277
    StepTimer2 = 0;    
278
  }  
279
280
  
281
  
282
  
283
  
284
  
285
286
      
287
  if( BEMFwinkel == 150 )
288
  {
289
    W150++;////////////
290
    if(stop3 == 0)
291
    {
292
      StepTime3 = StepTime; 
293
      stop3 = 1;    
294
    }
295
  }
296
  else
297
  {
298
    stop3 = 0;  
299
  }
300
  
301
302
  StepTimer3++;
303
  
304
  
305
  if( StepTimer3 >= StepTime3 + ( W90 * 1.5 ) )
306
  {
307
    sStep = 3;
308
    W90 = 0;/////////////////
309
    StepTimer3 = 0;    
310
  }
311
  
312
  
313
  
314
  
315
  
316
  
317
  
318
  
319
  if( BEMFwinkel == 210 )
320
  {
321
    W210++;////////////
322
    if(stop4 == 0)
323
    {
324
      StepTime4 = StepTime; 
325
326
      stop4 = 1;    
327
    }
328
  }
329
  else
330
  {
331
    stop4 = 0;  
332
  }
333
  
334
335
  StepTimer4++;
336
  
337
  
338
  if( StepTimer4 >= StepTime4 + ( W150 * 1.5 ) )
339
  {
340
    sStep = 4;
341
    W150 = 0;/////////////////
342
    StepTimer4 = 0;    
343
  }  
344
  
345
  
346
  
347
  
348
  
349
  
350
351
  
352
  
353
  if( BEMFwinkel == 270 )
354
  {
355
    W270++;////////////
356
    if(stop5 == 0)
357
    {
358
      StepTime5 = StepTime; 
359
360
      stop5 = 1;    
361
    }
362
  }
363
  else
364
  {
365
    stop5 = 0;  
366
  }
367
  
368
369
  StepTimer5++;
370
  
371
  
372
  if( StepTimer5 >= StepTime5 + ( W210 * 1.5 ) )
373
  {
374
    sStep = 5;
375
    W210 = 0;/////////////////
376
    StepTimer5 = 0;  
377
  }
378
  
379
  
380
  
381
  
382
  
383
  
384
  
385
  
386
  
387
  if( BEMFwinkel == 330 )
388
  {
389
    W330++;////////////
390
    if(stop6 == 0)
391
    {
392
      StepTime6 = StepTime; 
393
      stop6 = 1;    
394
    }
395
  }
396
  else
397
  {
398
    stop6 = 0;  
399
  }
400
  
401
402
  StepTimer6++;
403
  
404
  
405
  if( StepTimer6 >= StepTime6 + ( W270 * 1.5 ) )
406
  {
407
    sStep = 0;
408
    W270 = 0;/////////////////
409
    StepTimer6 = 0;  
410
  }  
411
412
413
414
415
  return sStep;
416
}




Ich konnte den Code noch nicht Testen, daher ist es sehr warscheinlich, 
das sich noch viele fehler darin befinden.
Ich hoffe ihr steigt da durch, und habt nicht allzuviel zu meckern :D



Achja der Motor ist ein Graupner Compact 260 8.4V

Er macht 9100 U/min
Anzahl der Pole: 14

: Bearbeitet durch User
von Andreas B. (bitverdreher)


Lesenswert?

So wie ich das sehe, verwendest Du simple Zählervariablen als Timer.
So geht das nicht. Dann sind die Zeiten abhängig vom Programablauf.
Lies Dir mal an, wie man Timer verwendet.
Aber um auf Deine ursprüngliche Frage zurückzukommen: Es kommt auch auf 
die Drehzahl an, die Du erreichen willst. (bzw.der Takt der max. am 
Motor anliegt.) Die konsequente Verwendung von 64 Bit Arithmetik íst 
auch nicht gerade der Geschwindigkeit dienlich. Da solltest Du mal etwas 
mehr Hirnschmalz investieren.
Ich behaupte mal, ordentlich programmiert, reicht 1MHz dicke aus.

Gruß
Andreas

Edit: OK, Motordaten hast Du nachgeliefert. D.h. Du hast einen Takt von 
14x9600/60 = 2123 Hz. Bei 1Mhz hast Du also ca. 470 Prozessor Takte pro 
Motortakt. Mit 64 Bit Arithmetik kannst Du das vergessen.

: Bearbeitet durch User
von Alex H. (sherlock)


Lesenswert?

Oh man dann muss ich da wohl nochmal ran...

Danke an alle!

von Andreas B. (bitverdreher)


Lesenswert?

Noch ein Tip:
Die Bitfolge der anzusteuernden Pins in ein 8-bit Array abspeichern und 
dann den kompletten Port in einem Rutsch mit dem indizierten Element 
beschreiben. Das braucht man nicht zur Laufzeit zusammenzubasteln.

Gruß
Andreas

von Amateur (Gast)


Lesenswert?

In der 4-er Version des Studios konnte man, wenn man sich im Debugger 
die Register angeschaut, feststellen wie viele Taktzyklen eine markierte 
Sequenz benötigt. Also Run von Markierung bis Markierung (Break-Point) 
und Cycle Counter vorher und nachher ablesen.

von Peter D. (peda)


Lesenswert?

Alex H. schrieb:
> signed long long  TSEC_ber

Damit versetzt Du dem AVR den Todesstoß.
Es geht schon damit los, daß ihm die Register ausgehen und er 
8Byte-Werte ständig ins RAM und zurück schaufeln muß.

Und die 7kB Code lassen vermuten, Du nimmst noch nen älteren AVR-GCC 
(<4.7), da sind 64Bit so richtig langsam.

von Max D. (max_d)


Lesenswert?

Ich würde mir vlt. den Code bestehender AVR-BLDC Projekte nehmen und 
entweder neu formulieren (falls du wegen Copyright nicht kopieren 
kannst) oder einfach die Teile rumschrauben die für dein Projekt anders 
müssen. Ich hatte jetzt nich den Nerv die 3-4 Seiten Code zu 
analysieren, aber das sieht nach einer Drehzahlregelung für den Motor 
aus (wieso du aber etwas an den Winkeln der Kommutierung verändern 
willst versteh ich nicht ganz, das verschwendet nur Leistung. 
Normalerweise nimmt man immer den Winkel mit der höchsten Kraft und 
schaltet dann "an der Spitze" die Power länger oder kürzer durch, 
dadurch kriegst du die besten Nm für dein Ampere.)

von m.n. (Gast)


Lesenswert?

Alex H. schrieb:
> #define F_CPU           1000000UL //1MHZ

Solange Dein µC mit angezogener Handbremse fährt, ist Deine Frage 
sinnfrei.
Bei einem ATmega32 sollten da 16MHz und einem ATmega324 (o.ä.) 20MHz 
stehen. Erst wenn das nicht reicht, hast Du ein Problem mit der 
Ausführungsgeschwindigkeit.

von Falk B. (falk)


Lesenswert?

@ Alex H. (sherlock)

>Ich hoffe ihr steigt da durch, und habt nicht allzuviel zu meckern :D

Doch. Lange Quelltexte gehören in den Anhang, siehe Netiquette.

>Achja der Motor ist ein Graupner Compact 260 8.4V

>Er macht 9100 U/min
>Anzahl der Pole: 14

Schön. Daraus kann man zumindest überschlägig was abschätzen. 9100U/Min 
= 152 U/s = 151 Hz. Ein normaler BLDC braucht bei Blockkommutierung 6 
Schritte/U, macht also ~1kHz. Das ist für einen heutigen Mikrocontroller 
laaanngsaaam. Selbst 10kHz sind bei halbwegs gescheiter Programmierung 
nicht allzu schnell, das sind immerhin 100us bzw. 2000 Takte bei 20MHz. 
Damit kann man SEHR viel anstellen, auch in C.

Achja, deine Quelltextformatierung ist verbesserungsfähig.

Strukturierte Programmierung auf Mikrocontrollern

von Wolfgang (Gast)


Lesenswert?

Alex H. schrieb:
> Ich hoffe ihr steigt da durch, und habt nicht allzuviel zu meckern :D

Doch, was soll das endlose Listing im Thread. Was meinst du, wofür es 
die Funktion "Dateianhang" gibt?

von Mark B. (markbrandis)


Lesenswert?

Frank M. schrieb:
> Stefan P. schrieb:
>> Setz im Programm an den Stellen wo nichts getan wird ein Pin auf High
>> und schau Dir das Puls/Pausen-Verhälntnis auf einem Oszi an. Damit
>> kannst Du deine µC-Load von 0..100% ausrechnen.
>
> Ich glaube, er will nicht die CPU-Last wissen, sondern wieviel Zeit
> bestimmte Teile seines Programms benötigen.

Auch das kann man mit der "Pin-High-Pin-Low-und-auf-Oszi-anschauen 
Methode" ermitteln.

von Peter D. (peda)


Lesenswert?

Mark Brandis schrieb:
> Auch das kann man mit der "Pin-High-Pin-Low-und-auf-Oszi-anschauen
> Methode" ermitteln.

Man könnte es aber auch ganz profan im Simulator laufen lassen und sich 
wahlweise die Zyklen oder µs zwischen 2 Breakpoints anzeigen lassen.

von MaWin (Gast)


Lesenswert?

> Ich konnte den Code noch nicht Testen

Grausamer Code.

Wenn er nicht schnell genau sein sollte, besteht massiv 
Optimierungspotential.

Und er ist nicht schnell genug, das sehe ich so schon:

Zu geringer CPU Takt

Zu grosse Variablenwerte (64 bit)

Zu viele if if if Vergleichsketten obwohl bei einer
Verzweigung ja schon klar ist daß die folgenden nie
dran kommen können (else) und immer wieder dasselbe
geprüft wird.

Und: Wie viele Instanzen von der Klasse sollen denn
gleichzeitig laufen ? Bei nur einem Motor machen
mehrere Instanzen keinen Sinn und damit die Klasse
an sich keinen Sinn.

Und ob das ganze jetzt überhaupt geeignet ist, einen
BLDC Motor zu bedienen, überblicke ich nicht, mir
fehlt der richtige Takt.

von Mark B. (markbrandis)


Lesenswert?

MaWin schrieb:
>> Ich konnte den Code noch nicht Testen
>
> Grausamer Code.
>
> Wenn er nicht schnell genau sein sollte, besteht massiv
> Optimierungspotential.

Ich persönlich würde zuerst mal die logischen Fehler beseitigen. Wenn 
der Code korrekt funktioniert im Sinne von: "Das richtige Ergebnis kommt 
heraus", dann würde ich anfangen zu optimieren.

Korrektes Funktionieren im Sinne eines "Unit Tests" muss man im übrigen 
(zunächst) nicht unbedingt auf der Zielplattform prüfen. Das kann man 
auch auf dem PC machen.

Jedenfalls, hier ist z.B. ein logischer Fehler:

1
uint16_t Treiber::Anlauf(uint16_t drehzahl_soll )
2
{
3
  uint16_t drehzahl_ist;
4
5
  
6
  if (drehzahl_ist<drehzahl_soll  )
7
  {
8
    drehzahl_ist += 1;
9
  }

drehzahl_ist ist eine lokale Variable, die auf dem Stack liegt, und 
somit nicht initialisiert. In der bedingten Verzweigung wird sie mit 
einer anderen Variablen verglichen. Wie soll da etwas Vernünftiges bei 
herauskommen?

Ach ja und die gleiche Methode:
uint16_t Treiber::Anlauf(uint16_t drehzahl_soll )
findet sich sowohl in der Datei work.cpp als auch in der Datei 
BLDC_Driver.cpp. Das geht doch so niemals durch Compiler und Linker.

Poste hier mal richtigen Code, als Dateianhang. Dann kann man anfangen 
übers Optimieren nachzudenken.

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

MaWin schrieb:
> Und: Wie viele Instanzen von der Klasse sollen denn
> gleichzeitig laufen ? Bei nur einem Motor machen
> mehrere Instanzen keinen Sinn und damit die Klasse
> an sich keinen Sinn.

Das kann man so pauschal nicht sagen. Vielleicht hat man im aktuellen 
Projekt tatsächlich nur einen Motor anzusteuern, plant aber schon die 
Erweiterung auf mehrere Motoren. Dann spricht auch nichts dagegen, den 
Code gleich so zu schreiben, dass er in Zukunft leichter erweiterbar 
ist.

Andererseits hab ich nicht den Eindruck, dass der Themenersteller schon 
soweit ist, dass dies sein größtes Problem wäre ;-)

von Walter (Gast)


Lesenswert?

Alex H. schrieb:

zum Code haben ja schon bemerkt das er noch großes 
Verbesserungspotenzial besitzt, hier noch ein Anfängerfehler
>   changeTime = 1/(drehzahl_ist/60)*1000000;

das ist meist gleichbedeutend mit
changeTime = 0;

von Alex H. (sherlock)


Lesenswert?

changeTime = 1/(drehzahl_ist(500U/min)/60)*1000000;
changeTime = 120000

warum ist das gleichbeduetent mit changeTime = 0?

von Mark B. (markbrandis)


Lesenswert?

1 als ganze Zahl geteilt durch eine (meist) viel größere ganze Zahl 
ergibt in Ganzzahlarithmetik nun einmal Null.

von Rolf Magnus (Gast)


Lesenswert?

Mark Brandis schrieb:
> 1 als ganze Zahl geteilt durch eine (meist) viel größere ganze Zahl
> ergibt in Ganzzahlarithmetik nun einmal Null.

Ob nun viel größer oder nicht ist egal. Wenn die Zahl betragsmäßig 
größer ist (also bei allem außer -1, 0 und 1), kommt 0 raus.

Alex H. schrieb:
> changeTime = 1/(drehzahl_ist(500U/min)/60)*1000000;
> changeTime = 120000
>
> warum ist das gleichbeduetent mit changeTime = 0?

In Ganzzahlarithmetik:

500/60 = 8
1/8 = 0
0 * 1000000 = 0

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.