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?
Die Codegröße hat doch rein gar nichts mit der Geschwindigkeit zu tun.
Indem Du das ausprobierst. Ansonsten: wenn Du mehr Infos rausrückst (Code), kann man das vielleicht abschätzen. Gruß Andreas
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.
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
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.
>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?
messen? pinwackeln (an passender Stelle im Programm zb Anfang main()) und die Frequenz messen
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.
Achso Danke, ich werde erstmal das mit dem Pinwackeln ausprobieren, das hört sich am Einfachsten an :)
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
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
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
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
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.
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.
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.)
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.
@ 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
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?
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.
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.
> 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.
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
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 ;-)
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;
changeTime = 1/(drehzahl_ist(500U/min)/60)*1000000; changeTime = 120000 warum ist das gleichbeduetent mit changeTime = 0?
1 als ganze Zahl geteilt durch eine (meist) viel größere ganze Zahl ergibt in Ganzzahlarithmetik nun einmal Null.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.