Forum: Mikrocontroller und Digitale Elektronik Anzahl CPU Takte ermitteln


von Holger K. (holgerkraehe)


Lesenswert?

Hallo zusammen

Ich habe folgenden Code:
1
void setLED(uint8_t Channel)
2
{
3
  switch (Channel)
4
  {
5
    case 0: IO_R_1;
6
      break;
7
    case 1: IO_G_1;
8
      break;
9
    case 2: IO_B_1;
10
      break;
11
  }
12
}
13
14
ISR(TIMER1_COMPB_vect)
15
{
16
  setLED(pwmChannel[pwmPos]);
17
18
  pwmPos++; //Nach dem ersten Durchlauf ist pwmPos 1
19
20
  if(pwmPos < 3)
21
  {
22
    //Ist neuer Wert pwmPos identisch mit altem?
23
    if(compValues[pwmPos] == compValues[pwmPos-1])
24
    {  //Wenn ja, setze auch die LED des zweiten werts!
25
      setLED(pwmChannel[pwmPos]);
26
      //Und erhöhe die position, da wir das zweite Element auch bereits abgearbeitet haben!
27
      pwmPos++; //Nun ist pwmPos 2. also bereits beim letzten wert!
28
29
      if(pwmPos < 3)
30
      {  //Ist neuer Wert pwmPos identisch mit altem?
31
        if(compValues[pwmPos] == compValues[pwmPos-1])
32
        {  //Wenn ja, setze auch die LED des zweiten werts!
33
          setLED(pwmChannel[pwmPos]);
34
          //Und erhöhe die position, da wir das zweite Element auch bereits abgearbeitet haben!
35
          pwmPos++; //Nun ist pwmPos 3. also wurden alle LEDs bereits aktiviert!
36
        }
37
      }
38
39
    }
40
  }
41
42
  //Wenn pwmPos kleiner als 3 ist, können wir einen neuen Wert setzen!
43
  //Andernfalls sind wir bereits am ende, und haben alle LEDs eingeschaltet!
44
  if(pwmPos < 3) OCR1B = compValues[pwmPos];
45
}


Nun möchte ich herausfinden, wie viele CPU_Takte dieser im worst_Case 
Benötigt, und ob ich irgendwo noch optimieren kann.

Wie kann ich den zugehörigen Assembler Code anzeigen lassen?

Danke schonmal!

von Ulrich F. (Gast)


Lesenswert?

Holger K. schrieb:
> Wie kann ich den zugehörigen Assembler Code anzeigen lassen?
1
avr-objdump -DS kompilierte.elf

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wieviel Threads willst du denn jetzt noch eröffnen für dein PWM Zeugs? 
Findest du nicht, das einer reicht? Und wie wäre es, wenn du dir endlich 
mal die Hinweise auf Soft PWM zu Herzen nimmst und dich da mal 
reinbuddelst.
Beitrag "Compare von Timer verschieben"
Beitrag "3Phasen PWM mit Atmega48"

von Holger K. (holgerkraehe)


Lesenswert?

Matthias S. schrieb:
> ieviel Threads willst du denn jetzt noch eröffnen für dein PWM Zeugs?

Man soll einen Thread pro Frage eröffnen.
Es handelt sich hierbei um eine andere Frage.

Zudem ist das PWM Problem grundsätzlich gelöst.

von Steffen R. (steffen_rose)


Lesenswert?

Holger K. schrieb:
> Man soll einen Thread pro Frage eröffnen.

Ich stimme dem zu.
Jedoch sollte dann in jeder Frage auch die nötigen Informationen über 
die Umgebung enthalten sein.

von Holger K. (holgerkraehe)


Lesenswert?

Steffen R. schrieb:
> Jedoch sollte dann in jeder Frage auch die nötigen Informationen über
> die Umgebung enthalten sein.

Stimmt.

Also es handelt sich um einen Atmega48 und AVR-GCC
Eclipse Indigo.

:)

Nachfolgend das Dissassembly.
Ich bin kein Experte für Assembler. Schätze die Ausführungszeit jedoch 
auf etwa 400 Takte.
1
0000081c <setLED>:
2
 81c:  81 30         cpi  r24, 0x01  ; 1
3
 81e:  31 f0         breq  .+12       ; 0x82c <setLED+0x10>
4
 820:  18 f0         brcs  .+6        ; 0x828 <setLED+0xc>
5
 822:  82 30         cpi  r24, 0x02  ; 2
6
 824:  29 f0         breq  .+10       ; 0x830 <setLED+0x14>
7
 826:  08 95         ret
8
 828:  5d 98         cbi  0x0b, 5  ; 11
9
 82a:  08 95         ret
10
 82c:  5b 98         cbi  0x0b, 3  ; 11
11
 82e:  08 95         ret
12
 830:  5e 98         cbi  0x0b, 6  ; 11
13
 832:  08 95         ret
14
15
00000834 <__vector_12>:
16
 834:  1f 92         push  r1
17
 836:  0f 92         push  r0
18
 838:  0f b6         in  r0, 0x3f  ; 63
19
 83a:  0f 92         push  r0
20
 83c:  11 24         eor  r1, r1
21
 83e:  2f 93         push  r18
22
 840:  3f 93         push  r19
23
 842:  4f 93         push  r20
24
 844:  5f 93         push  r21
25
 846:  6f 93         push  r22
26
 848:  7f 93         push  r23
27
 84a:  8f 93         push  r24
28
 84c:  9f 93         push  r25
29
 84e:  af 93         push  r26
30
 850:  bf 93         push  r27
31
 852:  ef 93         push  r30
32
 854:  ff 93         push  r31
33
 856:  e0 91 3a 01   lds  r30, 0x013A
34
 85a:  f0 e0         ldi  r31, 0x00  ; 0
35
 85c:  ec 5f         subi  r30, 0xFC  ; 252
36
 85e:  fe 4f         sbci  r31, 0xFE  ; 254
37
 860:  80 81         ld  r24, Z
38
 862:  dc df         rcall  .-72       ; 0x81c <setLED>
39
 864:  80 91 3a 01   lds  r24, 0x013A
40
 868:  8f 5f         subi  r24, 0xFF  ; 255
41
 86a:  80 93 3a 01   sts  0x013A, r24
42
 86e:  80 91 3a 01   lds  r24, 0x013A
43
 872:  83 30         cpi  r24, 0x03  ; 3
44
 874:  08 f0         brcs  .+2        ; 0x878 <__vector_12+0x44>
45
 876:  46 c0         rjmp  .+140      ; 0x904 <__vector_12+0xd0>
46
 878:  e0 91 3a 01   lds  r30, 0x013A
47
 87c:  f0 e0         ldi  r31, 0x00  ; 0
48
 87e:  ee 0f         add  r30, r30
49
 880:  ff 1f         adc  r31, r31
50
 882:  e9 5f         subi  r30, 0xF9  ; 249
51
 884:  fe 4f         sbci  r31, 0xFE  ; 254
52
 886:  20 81         ld  r18, Z
53
 888:  31 81         ldd  r19, Z+1  ; 0x01
54
 88a:  e0 91 3a 01   lds  r30, 0x013A
55
 88e:  f0 e0         ldi  r31, 0x00  ; 0
56
 890:  ee 0f         add  r30, r30
57
 892:  ff 1f         adc  r31, r31
58
 894:  eb 5f         subi  r30, 0xFB  ; 251
59
 896:  fe 4f         sbci  r31, 0xFE  ; 254
60
 898:  80 81         ld  r24, Z
61
 89a:  91 81         ldd  r25, Z+1  ; 0x01
62
 89c:  28 17         cp  r18, r24
63
 89e:  39 07         cpc  r19, r25
64
 8a0:  89 f5         brne  .+98       ; 0x904 <__vector_12+0xd0>
65
 8a2:  e0 91 3a 01   lds  r30, 0x013A
66
 8a6:  f0 e0         ldi  r31, 0x00  ; 0
67
 8a8:  ec 5f         subi  r30, 0xFC  ; 252
68
 8aa:  fe 4f         sbci  r31, 0xFE  ; 254
69
 8ac:  80 81         ld  r24, Z
70
 8ae:  b6 df         rcall  .-148      ; 0x81c <setLED>
71
 8b0:  80 91 3a 01   lds  r24, 0x013A
72
 8b4:  8f 5f         subi  r24, 0xFF  ; 255
73
 8b6:  80 93 3a 01   sts  0x013A, r24
74
 8ba:  80 91 3a 01   lds  r24, 0x013A
75
 8be:  83 30         cpi  r24, 0x03  ; 3
76
 8c0:  08 f5         brcc  .+66       ; 0x904 <__vector_12+0xd0>
77
 8c2:  e0 91 3a 01   lds  r30, 0x013A
78
 8c6:  f0 e0         ldi  r31, 0x00  ; 0
79
 8c8:  ee 0f         add  r30, r30
80
 8ca:  ff 1f         adc  r31, r31
81
 8cc:  e9 5f         subi  r30, 0xF9  ; 249
82
 8ce:  fe 4f         sbci  r31, 0xFE  ; 254
83
 8d0:  20 81         ld  r18, Z
84
 8d2:  31 81         ldd  r19, Z+1  ; 0x01
85
 8d4:  e0 91 3a 01   lds  r30, 0x013A
86
 8d8:  f0 e0         ldi  r31, 0x00  ; 0
87
 8da:  ee 0f         add  r30, r30
88
 8dc:  ff 1f         adc  r31, r31
89
 8de:  eb 5f         subi  r30, 0xFB  ; 251
90
 8e0:  fe 4f         sbci  r31, 0xFE  ; 254
91
 8e2:  80 81         ld  r24, Z
92
 8e4:  91 81         ldd  r25, Z+1  ; 0x01
93
 8e6:  28 17         cp  r18, r24
94
 8e8:  39 07         cpc  r19, r25
95
 8ea:  61 f4         brne  .+24       ; 0x904 <__vector_12+0xd0>
96
 8ec:  e0 91 3a 01   lds  r30, 0x013A
97
 8f0:  f0 e0         ldi  r31, 0x00  ; 0
98
 8f2:  ec 5f         subi  r30, 0xFC  ; 252
99
 8f4:  fe 4f         sbci  r31, 0xFE  ; 254
100
 8f6:  80 81         ld  r24, Z
101
 8f8:  91 df         rcall  .-222      ; 0x81c <setLED>
102
 8fa:  80 91 3a 01   lds  r24, 0x013A
103
 8fe:  8f 5f         subi  r24, 0xFF  ; 255
104
 900:  80 93 3a 01   sts  0x013A, r24
105
 904:  80 91 3a 01   lds  r24, 0x013A
106
 908:  83 30         cpi  r24, 0x03  ; 3
107
 90a:  68 f4         brcc  .+26       ; 0x926 <__vector_12+0xf2>
108
 90c:  e0 91 3a 01   lds  r30, 0x013A
109
 910:  f0 e0         ldi  r31, 0x00  ; 0
110
 912:  ee 0f         add  r30, r30
111
 914:  ff 1f         adc  r31, r31
112
 916:  e9 5f         subi  r30, 0xF9  ; 249
113
 918:  fe 4f         sbci  r31, 0xFE  ; 254
114
 91a:  80 81         ld  r24, Z
115
 91c:  91 81         ldd  r25, Z+1  ; 0x01
116
 91e:  90 93 8b 00   sts  0x008B, r25
117
 922:  80 93 8a 00   sts  0x008A, r24
118
 926:  ff 91         pop  r31
119
 928:  ef 91         pop  r30
120
 92a:  bf 91         pop  r27
121
 92c:  af 91         pop  r26
122
 92e:  9f 91         pop  r25
123
 930:  8f 91         pop  r24
124
 932:  7f 91         pop  r23
125
 934:  6f 91         pop  r22
126
 936:  5f 91         pop  r21
127
 938:  4f 91         pop  r20
128
 93a:  3f 91         pop  r19
129
 93c:  2f 91         pop  r18
130
 93e:  0f 90         pop  r0
131
 940:  0f be         out  0x3f, r0  ; 63
132
 942:  0f 90         pop  r0
133
 944:  1f 90         pop  r1
134
 946:  18 95         reti

: Bearbeitet durch User
von Carl D. (jcw2)


Lesenswert?

Zum schätzen würde ich ein PortPin am Start der ISR setzen und am Ende 
zurücksetzen. Logicanalyser dran und Mann sieht zumindest die 
"Applikationsdauer" der ISR. Für's Optimieren reicht dies aus, es soll 
ja schneller gehen.
Wer's genau braucht, muß eben Takte zählen (auch durch Schleifen) oder 
einen Simulator benutzen, der zählt in der Regel mit.

von 6a66 (Gast)


Lesenswert?

Carl D. schrieb:
> Wer's genau braucht, muß eben Takte zählen (auch durch Schleifen) oder
> einen Simulator benutzen, der zählt in der Regel mit.

Oder merkt sich am Anfag des zu messenden Teils einen freilaufenden 
Timer der z.B. mit 1us (oder bei höherer Auflösung mit 100ns) läuft. Am 
Ende nochmal auslesen und Differenz bilden. Lässt sich beim Debuggen 
schön auslesen.

Durchlaufzeit = Timer;
...
Durchlaufzeit = Durchlaufzeit - Timer;

rgds

von Holger K. (holgerkraehe)


Lesenswert?

taktvoll schrieb im Beitrag #4254927:
> @holger:  Glaubts du wirklich hier jemand zu finden, der dir diese
> Arbeit abnimmt? Für umme?
>
> Verachtender gehts wohl nicht?

Nö

Ich habe selbst gezählt.
Es gibt ja keine schleife.

somit kann ich stop-start rechnen = 274 Zeilen.
Gehe ich davon aus dass einige mehr als 1Takt benötigen mal 1.5 rechnen
= 411 Takte

Nun müsste ich das ganze eifach noch optimieren können.

von Peter II (Gast)


Lesenswert?

Holger K. schrieb:
> Nun müsste ich das ganze eifach noch optimieren können.

klar:

> setLED(pwmChannel[pwmPos]);

mache mal SetLED static. Wenn immer noch nicht weniger push und Pop sind 
dann inlinen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Holger K. schrieb:
> Nun möchte ich herausfinden, wie viele CPU_Takte dieser im worst_Case
> Benötigt
Simuliere den Code. Dort hast du dann einen Zykluszähler, der Taktgenau 
angibt, wie lang das gedauert hat...

Holger K. schrieb:
> Nun müsste ich das ganze eifach noch optimieren können.
Da ghets auch um das Thema und es wurde auch eine Lösung gefunden:
Beitrag "C versus Assembler->Performance"
Leider ist der Thread dann ein wenig aus dem Ruder gelaufen...

von Holger K. (holgerkraehe)


Lesenswert?

Peter II schrieb:
> mache mal SetLED static. Wenn immer noch nicht weniger push und Pop sind
> dann inlinen.

Danke habe ich gerade getestet.

Es bliebt unverändert.
Ich habe nun den Code von setLED direkt in die ISR geschrieben.
Ergebnis:
1
0000081c <__vector_12>:
2
 81c:  1f 92         push  r1
3
 81e:  0f 92         push  r0
4
 820:  0f b6         in  r0, 0x3f  ; 63
5
 822:  0f 92         push  r0
6
 824:  11 24         eor  r1, r1
7
 826:  2f 93         push  r18
8
 828:  3f 93         push  r19
9
 82a:  8f 93         push  r24
10
 82c:  9f 93         push  r25
11
 82e:  ef 93         push  r30
12
 830:  ff 93         push  r31
13
 832:  e0 91 3a 01   lds  r30, 0x013A
14
 836:  f0 e0         ldi  r31, 0x00  ; 0
15
 838:  ec 5f         subi  r30, 0xFC  ; 252
16
 83a:  fe 4f         sbci  r31, 0xFE  ; 254
17
 83c:  80 81         ld  r24, Z
18
 83e:  81 30         cpi  r24, 0x01  ; 1
19
 840:  39 f0         breq  .+14       ; 0x850 <__vector_12+0x34>
20
......

von Pete K. (pete77)


Lesenswert?

Was soll das Zählen von Takten beim Einschalten einer LED bringen? Das 
Auge ist sowieso viel zu träge, um eine Änderung in der Taktzahl 
signifikant zu erkennen.

von Peter II (Gast)


Lesenswert?

vermutlich ist auch compValues volatile. Wenn du das weglässt sollte der 
Code auch kleiner und schneller werden.

wie ist pwmPos definiert? Kannst es nicht static in der Funktion sein?

von Holger K. (holgerkraehe)


Lesenswert?

Peter II schrieb:
> vermutlich ist auch compValues volatile. Wenn du das weglässt
> sollte der
> Code auch kleiner und schneller werden.
>
> wie ist pwmPos definiert? Kannst es nicht static in der Funktion sein?

compValues ist tatsächlich Volatile.

compValues enthält die CompareWerte für den Zähler und entspricht 
deshalb auch dem DutyCycler einer LED.

diese Werte können mommentan im main angepasst werden.
Deshalb volatile. Im ISR werden diese aber nur gelesen und nie 
geschrieben!

pwmPos ist global als Volatile definiert.
pwmPos wird nur innerhalb zweier ISR verwendet.

Einmal beim überlauf des Zählers und dann im Vector12 bei Comparematch.
Dieser Wert wird sowohl gelesen als auch geschrieben im ISR
1
volatile unsigned char   pwmPos = 0;
2
volatile unsigned int   compValues[3] = {12000,13000,10000};
3
volatile unsigned char   pwmChannel[3] = {0,2,3}; //0=R,2=G,3=B - Dies definiert zu welchem Kanal die compValues gehören!

Ich konnten nun noch das switch-case konstrukt weglassen.
Ich schalte die LEDs nun damit ein:
1
PORTD |= PORTD | (0x08 << pwmChannel[pwmPos]);

in pwmChannel wird nun einfach definiert um wie viel das Bit geshiftet 
wird.

Meine LEDs liegen an PD3 PD5 und PD6

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Holger K. schrieb:
> diese Werte können mommentan im main angepasst werden.
> Deshalb volatile. Im ISR werden diese aber nur gelesen und nie
> geschrieben!

kommt auf den code in der main an. Vermutlich kann das volatile weg und 
es geht dann alles noch (und sogar schneller)

> pwmPos ist global als Volatile definiert.
> pwmPos wird nur innerhalb zweier ISR verwendet.
dann muss es nicht volatile sein.

von Christian (dragony)


Lesenswert?

Achja die alten Zeiten. Daran erinnere ich mich noch gut. Als ich mich 
das erste Mal mit Mikrocontrollern beschäftigt habe, war der Einstieg 
natürlich auch über C. Dann musste ich auch irgend wann einmal Takte 
zählen. Natürlich auch den ASM Code angeschaut (ohne vorher jemals ASM 
gesehen zu haben...) und solange rumoptimiert, bis die Takte nach 
einigen Stunden endlich gepasst haben.

Später musste ich in der gleichen Sub an einer ganz anderen Stelle, also 
ausserhalb des timing-kritischen Bereichs, einige Zeilen Code hinzufügen 
und plötzlich stimmten die Timings nicht mehr, weil C auf einmal die 
ganze Sub anders behandelt hat. Das war für mich der Ausschlag, mich 
endlich mal mit dem sadistischem ASM zu beschäftigen. Gerade bei uC 
Programmierung kommt es nämlich dauernd vor, dass die Takte eine Rolle 
spielen. Eigentlich bei jedem Protokoll. Selbst bei SPI und I2C, die 
zwar synchron arbeiten, jedoch auch dort Vorgaben über Mindesttaktlängen 
machen. Deshalb braucht es dann dort auch eine Art Balancing, damit es 
gut skalierbar ist.

Tja, was soll ich sagen, C fass ich nicht mehr an. ASM ist viel 
einfacher, wenn man mal ein System entwickelt hat, was funktioniert. 
Leider ist man da ziemlich auf sich und sein Hirn gestellt, da wirklich 
alles möglich ist und es so gut wie keine Vorgaben gibt. Die Lernkurve 
ist gar nicht mal so steil. Die paar Befehle hat man in 2 Tagen drin. 
Nur bis man ein System entwickelt hat, um nicht mit den ganzen Registern 
auf Kriegsfuss zu stehen, wenn man mal mehrere Subs in Subs aufruft, 
dauert es dann doch eine gewisse Zeit.

Ich vermisse C wie Zahnschmerzen, wenn ich nur an folgende Fragen denke, 
die ich mir dauernd stellen musste:
Welches Keyword brauche ich hier?
Was für einen internen Cast macht er hier?
Welchen Pointertyp muss ich jetzt hier konvertieren?
Wie viele Klammern will er jetzt hier haben?
Wie macht man das nochmal volatile? Ist das hier zwingend nötig?

Sicher werden jetzt einige C-Pros kommen und sagen "lerns halt, dann ist 
es doch einfach!". Nun, das gilt aber auch für ASM, nur habe ich da alle 
Freiheiten, ohne irgendwelche komischen Inline-Konstrukte zu basteln, 
die irgendwann kaum noch lesbar sind.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Christian S. schrieb:
> was soll ich sagen, C fass ich nicht mehr an. ASM ist viel einfacher
Darum geht es hier nicht und es interessiert hier keinen!
Kurz: es wird nicht schon wieder ein Thread gekapert.

> Sicher werden jetzt einige C-Pros kommen und sagen ...
Ich werde jeglichen Kommentar in Richtung Pro-Contra-C einfach löschen.
Es ist mir zu blöd, dass laufend irgendwer in irgendwelchen nicht von 
ihm gestarteten Threads unnötigerweise verkündet, wie toll Assembler 
doch ist.

von Carl D. (jcw2)


Lesenswert?

In einer ISR (Standard AVR, d.h. mit gesperrten INT's) sorgt volatile 
dafür, daß der Compiler den Wert nicht in einem Register zwischenlagern 
kann. Für globale Variablen (nicht HW-Register) gibt es aber niemand, 
der die, während die ISR läuft, ändern könnte. Braucht man also 
volatile, weil die Variable Daten von außen zur ISR, oder umgekehrt, 
oder beides, transportiert, dann kann man doch innerhalb der ISR lokale 
Kopien benutzen, das freut den Optimizer.
Bei mir haben die dann den Originalnames mit einem _ davor, werden am 
Anfang aus den Volatilen geladen und am Ende wieder in die Originale 
gespeichert. Spart je Zugriff auf eine Volatile ein LDS und eventuell 
ein STS, beide 2 Flash-Worte und 2 Takte. Da das Gänze aber die 
Registerlast erhöht, was zu mehr zu sichernden Registern führt, gilt wie 
immer: beide Varianten bezüglich des Ergebnisses vergleichen!

@Christian S.:
Fragen nach welcher Opcode macht was, Nebenwirkungen auf Flags, 
singned/unsigned-Gemeinheiten, etc. , stellen da natürlich nicht, da man 
das DB ja auswendig kennt ;-((
(wie viele Pseudonyme hat der dicke Fisch eigentlich noch?)

von Christian (dragony)


Lesenswert?

Hallo Lothar,

ich glaube, worum es hier geht, entscheidet der TO und so wie ich das 
interpretiert habe, ging es darum, die Anzahl der Takte eines bestimmten 
Codes zu wissen. Dass das in C alles andere als trivial ist, habe ich 
deutlich gemacht und gleichzeitig einen anderen Ansatz vorgeschlagen. 
Dabei ist es ja wohl auch mein Recht, darzulegen, dass ich mit meiner 
Entscheidung, nur noch in ASM zu programmieren, sehr zufrieden bin.

Ich werde mir in Zukunft die Zeit für solche Postings sparen. 
Anscheinend ist damit wirklich jedem geholfen. Mir wohl am meisten.

von Steffen R. (steffen_rose)


Lesenswert?

Holger K. schrieb:
> somit kann ich stop-start rechnen = 274 Zeilen.
> Gehe ich davon aus dass einige mehr als 1Takt benötigen mal 1.5 rechnen
> = 411 Takte

Ich kann es nicht ganz abschätzen, da ich auf diesem Prozessor nicht so 
sehr zu hause bin. Würde aber denken, dass der Faktor für die Schätzung 
viel zu niedrig ist.

- Befehle mit je 2/4 Byte lesen
- zusätzliche Speicherzugriffe (push, pop)

von Carl D. (jcw2)


Lesenswert?

Durch die Verwendung einer lokalen Kopie für RAM 0x13A (pwmPos) könnte 
man im ganz oben geposteten ASM-Listing 14 LDS/STS Zugriffe je 2 Takte 
sparen. Und da dies ein Index eines Arrays ist, käme noch jede Menge 
Pointer-Setup in Z, R30:R31 hinzu/bzw. weg. Zugriffe würden über LD Z+n 
gemacht.
Wobei es dabei nicht um das Tweaken des Maschinencodes geht, sondern 
darum, dem Compiler mitzuteilen, was Sache ist. Daß sich nämlich pmwPos 
innerhalb der ISR nicht magisch ändert (außerhalb schon, deshalb 
volatile). Man kann sich jetzt natürlich ein "volatile-weg" cast 
wünschen, oder man benutzt die gegebene(n) Vokabel/Gramatik, um sich 
verständlich zu machen. Andere Sprachen würden es mit
1
VAR pwmPos            : BYTE VOLATILE;
2
VAR pwmPosNonVolatile : BYTE AT pwmPos;
machen, ob das schöner ist, mag (besser nicht) diskutiert werden, oder 
brauchen volatile garnicht, weil das nur einen existierenden Optimizer 
überhaupt interessiert.

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.