Forum: Mikrocontroller und Digitale Elektronik Counter im ISR


von Sascha M. (stmech)


Lesenswert?

Hallo

wie kann man ̲ohne globale Variablen(!) eine Variable erstellen, die 
innerhalb von ISR funktioniert und zwischen 2 ISR Aufrufen sein Wert 
nicht verliert?

z.B
    ISR(Timer) // ISR jede 50ms aufgerufen
{
   uint8_t puffer[10]; // soll Werte zw. ISR Aufrufen behalten!

   do
   {
      puffer[i]=ADC; //10 Messwerte sollen im Array gespeichert werden

     /* Problem: ISR ist Timer-gesteuert und kann z.B. bei einem Wert 
i=5 unterbrechen und ISR wird dann von neuem aufgerufen. i muss aber vom 
Wert 5 weitermachen und nicht zu 0 zurückkehren. */

     i++;
   }while(i<10);
}

danke!

von Cyblord -. (cyblord)


Lesenswert?

Schlüsselwort static

aber warum keine globale- bzw. Modulvariable für so was nehmen?

von Peter D. (peda)


Lesenswert?


von Sascha M. (stmech)


Lesenswert?

Cyblord -. schrieb:
> Schlüsselwort static
>
> aber warum keine globale- bzw. Modulvariable für so was nehmen?

Hallo Cyblord, danke für die schnelle Antwort. Eine globale Variable ist 
in Aufgabestellung verboten, anscheinend um andere Möglichkeiten zu 
lernen. Danke noch mal! )

von Sascha M. (stmech)


Lesenswert?

wäre das dann richtig?
1
    ISR(Timer) // ISR jede 50ms aufgerufen
2
{
3
   static uint8_t puffer[10]; // soll Werte zw. ISR Aufrufen behalten!
4
   static int i = 0; /* würde i an dieser Stelle nicht bei jedem neuen                  ISR Aufruf wieder 0 werden?*/
5
6
   do
7
   {
8
      puffer[i]=ADC; //10 Messwerte sollen im Array gespeichert werden
9
10
     /* Problem: ISR ist Timer-gesteuert und kann z.B. bei einem Wert 
11
i=5 unterbrechen und ISR wird dann von neuem aufgerufen. i muss aber vom 
12
Wert 5 weitermachen und nicht zu 0 zurückkehren. */
13
14
     i++;
15
   }while(i<10);
16
}

von H.Joachim S. (crazyhorse)


Lesenswert?

static wurde ja schon genannt.
Bei meinem Compiler (CodeVision) führen static-Variablen gegenüber 
globalen allerdings zu mehr Code und zu mehr Laufzeit. Wenns kritisch 
wird (manchmal zählt gerade bei ISRs jeder Takt) nehme ich dann doch 
globale Variablen dafür her.

von Falk B. (falk)


Lesenswert?

@ Sascha M. (stmech)

>wäre das dann richtig?

Wenn man die schlechte Formatierung mal ignoriert, ist das so OK.

von Falk B. (falk)


Lesenswert?

@H.Joachim Seifert (crazyhorse)

>Bei meinem Compiler (CodeVision) führen static-Variablen gegenüber
>globalen allerdings zu mehr Code und zu mehr Laufzeit.

Dann würde ich das Ding wegwerfen, dann dafür gibt es keinerlei Grund. 
Physikalisch sind statische Variablen in Funktionen identisch zu 
globalen, nur dass sie nicht im globalen Namensraum auftauchen. Sie 
werden genauso wie globale beim Programmstart initialisiert und landen 
auch im gleichen Variablensegment.

von rmu (Gast)


Lesenswert?

Sascha M. schrieb:
> static int i = 0; /* würde i an dieser Stelle nicht bei jedem neuen
> ISR Aufruf wieder 0 werden?*/

nein, die Initialisierung wird nur beim ersten Aufruf durchgeführt. Je 
nach Compiler merkt sich der "irgendwo" in einem Flag, ob die 
Initialisierung durchgeführt wurde, dieses Flag wird dann auch bei jedem 
Aufruf der ISR überprüft, was ein paar Takte mehr Laufzeit kostet.

von Florian S. (sirius7)


Lesenswert?

Sascha M. schrieb:
> wäre das dann richtig?

also da, im ISR ganz oben static int i=0; deklariert ist, würde i an 
dieser Stelle doch ständig 0 werden und den Wert in der do while 
Schleife nicht behalten.

von H.Joachim S. (crazyhorse)


Lesenswert?

Der Grund ist, dass globale Variablen falls noch möglich in Registern 
gehalten werden, static-Variablen jedoch immer im RAM.

unsigned char ex0_count;

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
ex0_count++;

}

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
static unsigned char ex1_count;
ex1_count++;
}

  .CSEG
_ext_int0_isr:
; .FSTART _ext_int0_isr
  ST   -Y,R30
  IN   R30,SREG
; 0000 001F ex0_count++;
  INC  R4
; 0000 0020
; 0000 0021 }
  OUT  SREG,R30
  LD   R30,Y+
  RETI
; .FEND
;
;// External Interrupt 1 service routine
;interrupt [EXT_INT1] void ext_int1_isr(void)
; 0000 0025 {
_ext_int1_isr:
; .FSTART _ext_int1_isr
  ST   -Y,R30
  IN   R30,SREG
  ST   -Y,R30
; 0000 0026 static unsigned char ex1_count;
; 0000 0027 ex1_count++;
  LDS  R30,_ex1_count_S0000001000
  SUBI R30,-LOW(1)
  STS  _ex1_count_S0000001000,R30
; 0000 0028 }
  LD   R30,Y+
  OUT  SREG,R30
  LD   R30,Y+
  RETI
; .FEND

von Sascha M. (stmech)


Lesenswert?

ach sooo das macht mir jetzt nun alles klar! super, vielen Dank Euch 
allen für die freundliche Unterstützung!

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

> static int i = 0;

Wobei mein Lehrer dafür damals einen Punkt abgezogen hätte, denn alle 
globalen uns statischen Variablen werden ohnehin schon beim 
Programmstart mit 0 initialisiert.

Bei den damals aktuellen Compilern hätte man durch obige Code-Zeile die 
Variable zweimal mit 0 initialisiert, und damit unnötigen Code erzeugt.

Der aktuelle gcc optimiert das jedoch schön weg.

Ich persönlich bevorzuge die Angabe des Startwertes, wenn er für den 
Programmablsuf wichtig ist (auch wenn es 0 ist). So wird der Code besser 
lesbar.

Aber dein Lehrer sieht das möglicherweise anders, vor allem wenn er in 
den 80er Jahren stecken geblieben ist :-)

von Falk B. (falk)


Lesenswert?

@  rmu (Gast)

>> static int i = 0; /* würde i an dieser Stelle nicht bei jedem neuen
>> ISR Aufruf wieder 0 werden?*/

>nein, die Initialisierung wird nur beim ersten Aufruf durchgeführt.

Richtig. Genauer, vor dem Programmstart, so wie globale Variablen.

>Je
>nach Compiler merkt sich der "irgendwo" in einem Flag, ob die
>Initialisierung durchgeführt wurde, dieses Flag wird dann auch bei jedem
>Aufruf der ISR überprüft, was ein paar Takte mehr Laufzeit kostet.

Nein, das ist in C nicht so, nur in C++.

von rmu (Gast)


Lesenswert?

Sascha M. schrieb:
> rmu schrieb:
>
>> nein, die Initialisierung wird nur beim ersten Aufruf durchgeführt. Je
>> nach Compiler merkt sich der "irgendwo" in einem Flag, ob die
>> Initialisierung durchgeführt wurde, dieses Flag wird dann auch bei jedem
>> Aufruf der ISR überprüft, was ein paar Takte mehr Laufzeit kostet.
>
> ach sooo das macht mir jetzt nun alles klar!

In C++ wird die Variable beim ersten Aufruf der Funktion initialisiert, 
das muss dann in einem Flag vermerkt werden, und ist je nach C++-Version 
u.U. nicht thread-safe.

In C kann die Initialisierung zur Compile-Zeit erfolgen, ergo sollte es 
dann auch keinen Laufzeit-Overhead geben.

von Falk B. (falk)


Lesenswert?

@  H.Joachim Seifert (crazyhorse)

>Der Grund ist, dass globale Variablen falls noch möglich in Registern
>gehalten werden, static-Variablen jedoch immer im RAM.

???
Damit blockiert sich der Compiler DAUERHAFT CPU-Register? Ziemlicher 
Murks.
Solche Mikro-Testprogramme sind auch wenig praxisrelevant, denn wenn das 
Programm einen Tick größer wird ist es Essig mit freien Registern für 
globale Variablen.

von Stefan F. (Gast)


Lesenswert?

> Je nach Compiler merkt sich der "irgendwo" in einem Flag, ob die
> Initialisierung durchgeführt wurde

Ich hatte das so gelernt:

Im Flash Speicher befindet sich ein Array mit den Startwerten aller 
Variablen, die beim Programmstart initialisiert werden (diese static 
Variable gehört dazu).

Nach dem Reset aber bevor die main() Funktion gestartet wird, kopiert 
ein kleines Stück Code (den der Copmpiler einfügt) dieses Array ins RAM. 
Alle übrigen globalen und statischen Variablen werden mit 0 
initialisiert.

Ein Flag "irgendwo" ist daher gar nicht notwendig.

von Stefan F. (Gast)


Lesenswert?

> Damit blockiert sich der Compiler DAUERHAFT CPU-Register?
> Ziemlicher Murks.

Keineswegs, das ergibt kleine effiziente Programme. Bedenke, dass es µC 
mit sehr vielen Regitern gibt, wie die AVR Serie und die MCS51 Serie.

Meine Funk-Uhr, die dem Düsseldorfer Rheinturm nachempfunden wurde, 
hatte gar keine Variablen im RAM verwendet, sondern ausschließlich 
Register. Es war mehr als genug vorhanden.

Das war zwar Assembler, aber warum sollte der C Compiler nicht auch 
möglichst viele Register verwenden?

von Stefan F. (Gast)


Lesenswert?

> In C kann die Initialisierung zur Compile-Zeit erfolgen

Wie das? Der Compiler hat keinen Zugriff auf das RAM des 
Mikrocontrollers und außerdem ist RAM flüchtig. Wenn mein Compiler auf 
meinem PC die Variable wie auch immer initialisieren würden, dann dürfte 
ich mein Target niemals stromlos schalten. Denn dann verlieren sowohl 
RAM als auch Register ihren Inhalt.

von H.Joachim S. (crazyhorse)


Lesenswert?

Kann man ja einstellen, ob man das will oder nicht (automatic global 
register allocation). Gilt dann für R4-R15. Globale Variablen (nur char 
und int, long nicht) werden dann in den Registern gehalten in der 
Reihenfolge der Deklaration. Ich finds praktisch und seh keinen Nachteil 
darin, sondern den schon erwähnten Vorteil, zeitkritische Sachen so 
schnell wie eben möglich erledigen zu können.

von Falk B. (falk)


Lesenswert?

@:  Stefan Us (stefanus)

>> Damit blockiert sich der Compiler DAUERHAFT CPU-Register?
>> Ziemlicher Murks.

>Keineswegs, das ergibt kleine effiziente Programme. Bedenke, dass es µC
>mit sehr vielen Regitern gibt, wie die AVR Serie und die MCS51 Serie.

Eben, nur bei SEHR kleinen Programmen geht so was. Sobald die ETWAS 
größer werden geht das nicht mehr!

>Meine Funk-Uhr, die dem Düsseldorfer Rheinturm nachempfunden wurde,
>hatte gar keine Variablen im RAM verwendet, sondern ausschließlich
>Register. Es war mehr als genug vorhanden.

Jaja, und gleich kommt Moby und erklärt uns, daß Variablen im RAM 
Verschwendung und überflüssig sind ;-)

>Das war zwar Assembler, aber warum sollte der C Compiler nicht auch
>möglichst viele Register verwenden?

Das tut er auch, aber anders als ein eng fokussierter ASM-Fan.
Die Strategie zur Registernutzung ist gar nicht soo einfach. Globale 
Variablen dauerhaft in CPU-Registern zu halten ist nur in sehr wenigen 
Ausnahmefällen sinnvoll und möglich.

von Falk B. (falk)


Lesenswert?

@  Stefan Us (stefanus)

>> In C kann die Initialisierung zur Compile-Zeit erfolgen

>Wie das?

Weil das der C Standard so definiert hat!

>Der Compiler hat keinen Zugriff auf das RAM des
>Mikrocontrollers

Bitte?

> und außerdem ist RAM flüchtig. Wenn mein Compiler auf
>meinem PC die Variable wie auch immer initialisieren würden, dann dürfte
>ich mein Target niemals stromlos schalten. Denn dann verlieren sowohl
>RAM als auch Register ihren Inhalt.

Du sprichst wirr.

von Falk B. (falk)


Lesenswert?

@  H.Joachim Seifert (crazyhorse)


>Kann man ja einstellen, ob man das will oder nicht (automatic global
>register allocation). Gilt dann für R4-R15. Globale Variablen (nur char
>und int, long nicht) werden dann in den Registern gehalten in der
>Reihenfolge der Deklaration.

OK, das klingt brauchbar.

>Ich finds praktisch und seh keinen Nachteil
>darin, sondern den schon erwähnten Vorteil, zeitkritische Sachen so
>schnell wie eben möglich erledigen zu können.

Naja, die allerwenigsten ISRs sind auf 1 Takt mehr oder weniger wirklich 
angewiesen. Extremfälle kann man immer konstruieren.

von avr (Gast)


Lesenswert?

Falk B. schrieb:
> @  Stefan Us (stefanus)
>
>>> In C kann die Initialisierung zur Compile-Zeit erfolgen
>
>>Wie das?
>
> Weil das der C Standard so definiert hat!

Jaja, also wenn ich mein Programm kompiliere ist der µC schon 
initialisiert. Und das obwohl er noch in der ESD-Tüte ist...
Geht das über Verschränkung? Woher weiß der Compiler denn welchen µC ich 
denn initialisieren möchte?

Also nochmal für dich: Den Ram kann der Compiler nur über irgendwelchen 
Code initialisieren. Genauso wie die Register. Und initialisiert wird 
genau dann, wenn dieser Code ausgeführt wird, also zur Laufzeit.

von H.Joachim S. (crazyhorse)


Lesenswert?

@Falk: klar, meist ist es nicht nötig. Aber es gibt dennoch immer wieder 
mal Sachen, wo man auf der Suche nach Optimierungen ist.
Und in dem obigen kleinen Beispiel ist es nicht 1 Takte Unterschied, 
sondern 8. Und 6 word Programmspeicher. Spielt auch in den allermeisten 
Fällen  keine Rolle, aber ich habe auch schon Fälle gehabt, wo man durch 
nachträgliche Softwareerweiterungen bedenklich nahe an die 
Programmspeichergrösse kam...

Was macht eigentlich der gcc mit R2-R15? Werden die tatsächlich für 
irgendwas benutzt oder liegen die eh brach?

von Oliver S. (oliverso)


Lesenswert?

Stefan U. schrieb:
>> In C kann die Initialisierung zur Compile-Zeit erfolgen
>
> Wie das? Der Compiler hat keinen Zugriff auf das RAM des
> Mikrocontrollers

Das war halt etwas mißverständlich ausgedrückt. Natürlich erfolgt die 
Initialisierung durch ein ablaufendes Programm, aber es erfolgt vor dem 
eigentlichen C-Programm. Aus Sicht des C-Programmierers damit nicht zur 
Laufzeit seines Programms.

Oliver

von Falk B. (falk)


Lesenswert?

@  avr (Gast)

>> Weil das der C Standard so definiert hat!

>Jaja, also wenn ich mein Programm kompiliere ist der µC schon
>initialisiert. Und das obwohl er noch in der ESD-Tüte ist...

Jaja.

>Geht das über Verschränkung?

Besser als Beschränkung, die du hier hervorragend demonstrierst!

>Also nochmal für dich: Den Ram kann der Compiler nur über irgendwelchen
>Code initialisieren. Genauso wie die Register.

Das hat doch keiner bestritten.

> Und initialisiert wird
>genau dann, wenn dieser Code ausgeführt wird, also zur Laufzeit.

Jain. Einfach mal lesen und 5 Sekunden nachdenken, bevor hier wild 
rumposaunt wird.

In C (NICHT C++ !) werden globale sowie statische Variablen VOR der 
Ausführung von main() einmalig initialisiert. In einer Funktion mit 
statischen Variablen wird NICHT noch einmal eine Initialisierung oder 
gar Prüfung auf diese erstmalige Initialisierung durchgeführt! Damit ist 
die praktische Anwendung von globalen und statischen Variablen nahezu 
gleich. Der Unterschied liegt nur darin, daß globale Variablen global 
sichtbar sind, lokale statische Variablen nur lokal.

von Oliver S. (oliverso)


Lesenswert?

Falk B. schrieb:
>>Je
>>nach Compiler merkt sich der "irgendwo" in einem Flag, ob die
>>Initialisierung durchgeführt wurde, dieses Flag wird dann auch bei jedem
>>Aufruf der ISR überprüft, was ein paar Takte mehr Laufzeit kostet.
>
> Nein, das ist in C nicht so, nur in C++.

Hm. Seit wann das den?

In dem hier besprochen Fall
1
 static int foo = 42;

innerhalb einer Funktion wird die Initialiserung auch in C++ vor dem 
Start von main ausgeführt. Da gibt's keine Flags oder ähnliches.

Oliver

von Falk B. (falk)


Lesenswert?

@ H.Joachim Seifert (crazyhorse)

>nachträgliche Softwareerweiterungen bedenklich nahe an die
>Programmspeichergrösse kam...

Hatte ich auch mal, da war ein AT8515 mit nur noch ACHT Bytes freiem 
Flash!
In der nächsten Revision wurde es dann ein ATmega644 ;-)

>Was macht eigentlich der gcc mit R2-R15?

Benutzen.

> Werden die tatsächlich für
>irgendwas benutzt

Ja sicher!

> oder liegen die eh brach?

Keinesfalls!

von Stefan F. (Gast)


Lesenswert?

>>Der Compiler hat keinen Zugriff auf das RAM des
>>Mikrocontrollers

>Bitte?

Der Compiler kann nur Code (und feste Datenstrukturen(also keine 
Variablen)) erzeugen, den ich anschließend mit dem Programmiertool in 
den Flash Speicher des Mikrocontrollers übertrage.

Der Compiler hat keinen Zugriff auf die Ziel-Hardware, daher kann er sie 
nicht initialisieren. Er kann lediglich Code erzeugen, der diese 
Initialisierung ZUR LAUFZEIT durchführt.

Das ist bei PC-Software nicht anders. Wenn ich auf meinem PC ein 
Programm compiliere, dass du später ausführst, dann kann der Compiler 
unmöglich deine RAM initialisieren. Er hat ja gar keine Verbindung zu 
deiner Maschine.

von Axel S. (a-za-z0-9)


Lesenswert?

rmu schrieb:
> Sascha M. schrieb:
>> static int i = 0; /* würde i an dieser Stelle nicht bei jedem neuen
>> ISR Aufruf wieder 0 werden?*/
>
> nein, die Initialisierung wird nur beim ersten Aufruf durchgeführt.

Falsch. Statische Variablen werden praktisch immer zusammen mit
initialisierten globalen Variablen intialisiert. Und zwar noch
bevor(!) die main() Funktion aufgerufen wird.

> Je nach Compiler merkt sich der "irgendwo" in einem Flag, ob die
> Initialisierung durchgeführt wurde, dieses Flag wird dann auch bei jedem
> Aufruf der ISR überprüft, was ein paar Takte mehr Laufzeit kostet.

Zeigen.

Wenn es einen solchen Compiler gibt (was ich erst glaube wenn ich
es sehe) denn gehört der weggeworfen. Weit.

von avr (Gast)


Lesenswert?

Falk B. schrieb:
> In C (NICHT C++ !) werden globale sowie statische Variablen VOR der
> Ausführung von main() einmalig initialisiert.

Keine Ahnung wie genau Laufzeit definiert wird. Für mich gehört zur 
Laufzeit auch sämtlicher Startup-Code. Aber der gehört definitiv nicht 
zur Compile-Zeit! Compile-Zeit ist während dem kompilieren. Soviel dazu:

Falk B. schrieb:
> Jain. Einfach mal lesen und 5 Sekunden nachdenken, bevor hier wild
> rumposaunt wird.

H.Joachim S. schrieb:
> Was macht eigentlich der gcc mit R2-R15? Werden die tatsächlich für
> irgendwas benutzt oder liegen die eh brach?

Wenn ich mich richtig erinnere müssen gerade diese Register bei 
Funktionsaufrufen nicht gesichert werden. Der Compiler packt da gerne 
Variablen rein, anstatt sie dauernd auf den Stack zu legen. Die Anzahl 
der Stackoperationen wird sicherlich stark steigen, wenn man ihm diese 
Register nimmt.

von Peter II (Gast)


Lesenswert?

Oliver S. schrieb:
> Hm. Seit wann das den?
>
> In dem hier besprochen Fall static int foo = 42;
> innerhalb einer Funktion wird die Initialiserung auch in C++ vor dem
> Start von main ausgeführt. Da gibt's keine Flags oder ähnliches.

doch gibt es
1
#include <stdio.h>
2
class cx
3
{
4
public:
5
   cx() {
6
      printf("init\n");
7
   }
8
};
9
10
void foo() {
11
   static cx x;
12
}
13
14
int main() {
15
  printf("start\n");
16
  foo();
17
  printf("next\n");
18
  foo();
19
  return 0;
20
};

von Axel S. (a-za-z0-9)


Lesenswert?

Peter II schrieb:
> Oliver S. schrieb:
>> Hm. Seit wann das den?
>>
>> In dem hier besprochen Fall static int foo = 42;
>> innerhalb einer Funktion wird die Initialiserung auch in C++ vor dem
>> Start von main ausgeführt. Da gibt's keine Flags oder ähnliches.
>
> doch gibt es

(schnipp)

Äpfel und Birnen. Nochmal für dich:

>> In dem hier besprochen Fall static int foo = 42;

von Pandur S. (jetztnicht)


Lesenswert?

>   ISR(Timer) // ISR jede 50ms aufgerufen
>{
>   static uint8_t puffer[10];
>   static int i = 0;
>   do  {
>      puffer[i]=ADC;
>      i++;  }
>    while(i<10);
>}


ist Murks, denn ein ADC Aufruf ist nicht instantan.

von Peter D. (peda)


Lesenswert?

Sascha M. schrieb:
> /* Problem: ISR ist Timer-gesteuert und kann z.B. bei einem Wert
> i=5 unterbrechen und ISR wird dann von neuem aufgerufen. i muss aber vom
> Wert 5 weitermachen und nicht zu 0 zurückkehren. */

Nach jeder Unterbrechrung macht die CPU genau da weiter, wo sie 
unterbrochen wurde. Das gilt auch für nested Interrupts.
Ein static ist daher fehl am Platze.
Hier würde die Schleife  mit i = 10 verlassen, d.h. die Schleife wird 
nie wieder ausgeführt.

von Klaus H. (klummel69)


Lesenswert?

Oder D. schrieb:
> ist Murks, denn ein ADC Aufruf ist nicht instantan.

Verstehe hier den Begirff "instantan" nicht. Kannst Du erklären was Du 
meinst?

@Sascha M.
Erkläre mal was nach dem Code-Auschnitt im weiteren Verlauf gemacht 
werden soll.

von Pandur S. (jetztnicht)


Lesenswert?

> Verstehe hier den Begirff "instantan" nicht. Kannst Du erklären was Du
meinst?


Der Befehl
>    puffer[i]=ADC;

wird nicht in einem clock abgearbeitet, nehm ich an.
Die Memory mapped ADC sind sehr unueblich.
Dauert viel zu lange. Dh man darf nicht in einem Timerinterrupt lesen. 
Sondern im main, oder im ADC Interrupt.

: Bearbeitet durch User
von Cyblord -. (cyblord)


Lesenswert?

Oder D. schrieb:
>> Verstehe hier den Begirff "instantan" nicht. Kannst Du erklären was Du
> meinst?
>
>
> Der Befehl
>>    puffer[i]=ADC;
>
> wird nicht in einem clock abgearbeitet, nehm ich an.
Was macht es ob es nun 1 Clock oder 10 Clocks sind? Es werden lediglich 
2 Register gelesen und in eine 16 Bit Variable gesteckt.

Natürlich läuft das nicht synchron zum ADC Trigger. Der ADC wird 
freilaufend sein nehme ich an.
Wenn aber die Aufrufzeit zwischen den ISR hinreichend lang ist, spielt 
das keine Rolle.

von avr (Gast)


Lesenswert?

Cyblord -. schrieb:
> Was macht es ob es nun 1 Clock oder 10 Clocks sind? Es werden lediglich
> 2 Register gelesen und in eine 16 Bit Variable gesteckt.
>
> Natürlich läuft das nicht synchron zum ADC Trigger. Der ADC wird
> freilaufend sein nehme ich an.
> Wenn aber die Aufrufzeit zwischen den ISR hinreichend lang ist, spielt
> das keine Rolle.

Der nächste der nicht lesen kann. Hier war mal so ein Zitat:

> Einfach mal lesen und 5 Sekunden nachdenken, bevor hier wild
> rumposaunt wird.

Der ADC wird in der Schleife 10 mal eingelesen. Ich nehme an, dass der 
ADC nicht so schnell ist, bzw. der Controller so langsam getaktet wird, 
dass man bei jedem Schleifendurchlauf einen neuen ADC-Wert bekommt. Es 
macht keinen Sinn ein Register 10 mal auszulesen, wenn es sich in der 
Zeit nicht ändert.

von rmu (Gast)


Lesenswert?

Axel S. schrieb:
> rmu schrieb:
>> Sascha M. schrieb:
>>> static int i = 0; /* würde i an dieser Stelle nicht bei jedem neuen
>>> ISR Aufruf wieder 0 werden?*/
>>
>> nein, die Initialisierung wird nur beim ersten Aufruf durchgeführt.
>
> Falsch. Statische Variablen werden praktisch immer zusammen mit
> initialisierten globalen Variablen intialisiert. Und zwar noch
> bevor(!) die main() Funktion aufgerufen wird.

wie weiter unten geschrieben war ich im c++ modus. sorry.

>> Je nach Compiler merkt sich der "irgendwo" in einem Flag, ob die
>> Initialisierung durchgeführt wurde, dieses Flag wird dann auch bei jedem
>> Aufruf der ISR überprüft, was ein paar Takte mehr Laufzeit kostet.
>
> Zeigen.
>
> Wenn es einen solchen Compiler gibt (was ich erst glaube wenn ich
> es sehe) denn gehört der weggeworfen. Weit.

vermutlich. aber wenn man in c++ sowas wie "static int i = f();" 
verwendet oder ein objekt mit nicht-trivialem constructor anlegt dann 
gibts ein flag was merkt ob initialisiert wurde oder nicht.

von Amateur (Gast)


Lesenswert?

Anno Studio 4.?? gab es eine genaue Beschreibung, welche Register der 
GNU-Compiler verwendet.
Es würde mich wundern, wenn es zu den aktuellen Versionen so etwas nicht 
mehr gibt.
Andernfalls könnte man ja Assembler (z.B. in der ISR), im gemischten 
Modus, auch nicht nutzen.
Wenn ich mich richtig erinnere, waren das die Register 0,1 (rund um die 
Division) und 2 (für Null). Dann war Ruhe bis incl. R15.
Ab R16 galt dann (a)uf (e)igene (G)efahr (Zeiger, Variablen, usw.).
Ob die Register R3 bis R15 würglich nicht genutzt wurden, oder ob push 
und pop dafür herhalten mussten, weiß ich aber nicht mehr.

von Falk B. (falk)


Lesenswert?

@ Amateur (Gast)

>Anno Studio 4.?? gab es eine genaue Beschreibung, welche Register der
>GNU-Compiler verwendet.

Wirklich?

>Andernfalls könnte man ja Assembler (z.B. in der ISR), im gemischten
>Modus, auch nicht nutzen.

Doch. Denn bei Inlineassembler schreibt man meistens keine direkten 
Registrnamen sondern symbolische Platzhalter und der Compiler sucht sich 
dann ein freies Register aus.

>Wenn ich mich richtig erinnere, waren das die Register 0,1 (rund um die
>Division) und 2 (für Null). Dann war Ruhe bis incl. R15.

Nein, auch R3-R15 werden benutzt.

>Ab R16 galt dann (a)uf (e)igene (G)efahr (Zeiger, Variablen, usw.).

Nein, denn man sollte sich so oder so an die Vorgaben des Compiler zum 
Thema Inline-Assembler halten. Es sei denn, man schreibt die komplette 
ISR in ASM.

von spess53 (Gast)


Lesenswert?

HI

>Wenn ich mich richtig erinnere, waren das die Register 0,1 (rund um die
>Division) und 2 (für Null).

Du erinnerst dich falsch:

https://gcc.gnu.org/wiki/avr-gcc

MfG Spess

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.