Forum: Compiler & IDEs Naked ISR hier ok?


von Ingo L. (corrtexx)


Lesenswert?

Hallo,

ich habe ein paar Zeilen Code, es spielt sich absolut alles in der ISR 
ab, von daher ist die Frage, ob die ISR hier "naked" sein darf. Der 
Pro-/Epilog einer normalen ISR macht schon ganz ordentlich Laufzeit bei 
einem Systemtakt von 128kHz.
1
int main ( void )
2
{
3
  _delay_ms( 100 );
4
5
  // Pulse Output
6
  PULSE_HIGH();
7
  PULSE_DDR |= (1<<PULSE_PIN);
8
  
9
  // Disable AD-Comp
10
  ACSR |= (1<<ACD);
11
  
12
  // Unused Pin low
13
  DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB4);
14
  PORTB &= ~( (1<<PB2) | (1<<PB3) | (1<<PB4) );
15
  
16
  //Setup AVR
17
  OCR0A = 111;
18
  TCCR0A |= (1<<WGM01);      // CTC
19
  TCCR0B |= (1<<CS00);      // Prescaler = 1
20
  TIMSK0 |= (1<<OCIE0A);      // Interrupt enabler
21
  
22
  //External Interrupt
23
  PORTB |= (1<<PB1);          // internal Pullup enable
24
  MCUCR |= (1<<ISC01);        // Trigger on falling edge
25
  CLEAR_SENSOR_FLAG();
26
  
27
  // Global Interrupt enable
28
  sei();
29
  
30
    /* Nice weather... */
31
    while ( "Cycling" );
32
}
33
34
35
ISR ( TIMEBASE_1MS, ISR_NAKED )
36
{
37
  static uint16_t TimeCounter = 0;
38
  static uint16_t RoundTrip[2] = {0,0};
39
  static uint16_t TimeDifference = PULSE_PERIOD_MAX_MS;
40
  static uint16_t Pulsegenerator = UINT16_MAX;
41
  static uint16_t TunedOutputPeriod = PULSE_PERIOD_MAX_MS;
42
  static uint16_t Timeout = ZERO_TIME_DETECT;
43
44
  // Nullerkennung
45
  if ( Timeout ) Timeout--;
46
47
  // Impuls Erfassung  
48
  TimeCounter++;
49
  
50
  if ( SENSOR_TRIGGERD ){
51
    Timeout = ZERO_TIME_DETECT;
52
    CLEAR_SENSOR_FLAG();
53
    RoundTrip[NEW] = TimeCounter;
54
    TimeDifference = RoundTrip[NEW] - RoundTrip[OLD];
55
    RoundTrip[OLD] = RoundTrip[NEW];
56
  }
57
58
  // Impuls Ausgabe
59
  if ( TimeDifference < PULSE_PERIOD_MIN_MS ){ // abgeregelt
60
    TunedOutputPeriod = PULSE_PERIOD_MIN_MS;
61
  }else{// unmanipuliert
62
    TunedOutputPeriod = TimeDifference;
63
  }
64
  
65
  if ( TunedOutputPeriod > PULSE_PERIOD_MAX_MS ) TunedOutputPeriod = PULSE_PERIOD_MAX_MS; 
66
  
67
  if ( Pulsegenerator >= TunedOutputPeriod ) Pulsegenerator = 0;
68
  else Pulsegenerator++;
69
  
70
  if ( Pulsegenerator < PULSE_DURATION_MS && Timeout ) PULSE_LOW();
71
  else PULSE_HIGH();
72
73
  reti();
74
}

Funktionieren tut es, aber gibts hier irgendwelche Fallstricke?

von Oliver S. (oliverso)


Lesenswert?

Rein theoretisch sollte die Endlosschleife im Hauptprogramm zu einem 
einfachen jmp zusammenschrumpfen, dem es egal ist, ob die ISR 
zwischenzeitlich Register oder Flags ändert.

Rein praktisch solltest du dir den generierten Assemblercode anschauen, 
ob das auch so tatsächlich ist.

Oliver

von Ingo L. (corrtexx)


Lesenswert?

1
 8c:  ff cf         rjmp  .-2        ; 0x8c <main+0x44>
ja, passiert

von Bernd K. (prof7bit)


Lesenswert?

Ich würde mir überlegen ob es in diesem konkreten Fall nicht sogar 
sinnvoller wäre komplett auf den Interrupt zu verzichten und 
stattdessen in der main-loop das entsprechende Timer-Bit zu pollen und 
alles in der main zu machen.

von Ingo L. (corrtexx)


Lesenswert?

Bernd K. schrieb:
> Ich würde mir überlegen ob es in diesem konkreten Fall nicht sogar
> sinnvoller wäre komplett auf den Interrupt zu verzichten und
> stattdessen in der main-loop das entsprechende Timer-Bit zu pollen und
> alles in der main zu machen.
Wo wäre da der Vorteil gegenüber der jetzigen Lösung? Ich würde sie in 
diesem Fall sogar als absolut gleichwertig sehen

von Peter D. (peda)


Lesenswert?

Ingo L. schrieb:
> Wo wäre da der Vorteil gegenüber der jetzigen Lösung? Ich würde sie in
> diesem Fall sogar als absolut gleichwertig sehen

Nö, die Loop hat mehrere Vorteile:
Bit testen, löschen und zurück springen geht schneller als 
Interrupteinsprung und Return.
Der Compiler merkt, daß die Loop nie verlassen wird und
wird viele Variablen in Registern halten.

Ingo L. schrieb:
>     while ( "Cycling" );

Ist jetzt nicht so die feine Art, einen Stringpointer als Bool zu 
vergewaltigen.
C erlaubt viele Schweinereien, man sollte sie aber nicht grundlos 
verwenden.
Heutzutage ist es hip, der Lesbarkeit den Vorzug zu geben.

von Bernd K. (prof7bit)


Lesenswert?

Peter D. schrieb:
>>     while ( "Cycling" );
>
> C erlaubt viele Schweinereien, man sollte sie aber nicht grundlos
> verwenden.
> Heutzutage ist es hip, der Lesbarkeit den Vorzug zu geben.

Also wenn lesbar dann so:

while ("my guitar gently weeps");

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Peter D. schrieb:
> Bit testen, löschen und zurück springen geht schneller als
> Interrupteinsprung und Return.

Dafür kann man hier keinen Power Down Modus nutzen; wenn man Interrupts 
nimmt, kann man in der while-Schleife einen solchen aktivieren um 
Energie zu sparen. Beim AVR braucht das aber ggf. Register-Zugriffe...

von Bernd K. (prof7bit)


Lesenswert?

Ingo L. schrieb:
>> stattdessen in der main-loop das entsprechende Timer-Bit zu pollen und
>> alles in der main zu machen.
> Wo wäre da der Vorteil gegenüber der jetzigen Lösung? Ich würde sie in
> diesem Fall sogar als absolut gleichwertig sehen

Konkretes Beispiel:

Ich hab hier einen aktuellen Fall wo ich eine 80kHz PLL auf einem Silabs 
8051 (EFM8BB10) implementierte. Der erste Versuch verwendete den 
ADC-Interrupt (der dann mit 320kHz kam) und fast die ganze CPU-Zeit ging 
dafür drauf in den Interrupt hinein und wieder hinaus zu springen, 
zusätzlich noch der Overhead bis 4 zu zählen und jedesmal zu schauen 
welche der 4 Werte (I, Q, -I, -Q) jetzt gerade gesampelt wurde. Ich war 
schon bei 80% CPU allein vom Grundgerüst ohne schon irgendwas anderes zu 
machen als nur Samples einzulesen und zuzuordnen. Die Zeit hat nicht 
mehr gereicht noch irgendwas sinnvolles damit zu machen, es ging so 
nicht.

Im zweiten Anlauf machte ich eine main-loop die pro Durchlauf 4 mal auf 
das conversion complete bit wartet, danach jeweils ein bisschen was tut 
(erst dies, dann das, eben alles was einmal pro Periode zu tun ist schön 
verteilt), die Zeit reicht jetzt gut aus für alles und könnte jetzt 
sogar bis 100kHz gehen wenn ich wollte.

von egberto (Gast)


Lesenswert?

Wenn das mal richtig läuft, kannst du den kompletten Code ja unter 
"Fahrzeugelektronik" Thema E-Bike Tuning posten ;-)


Grüße,

egberto

von Thomas S. (thschl)


Lesenswert?

Bernd K. schrieb:
> while ("my guitar gently weeps");

dann lieber was sinnvolles und  my_boobs_gently_weeps als TRUE 
definieren

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Niklas G. schrieb:
> Beim AVR braucht das aber ggf. Register-Zugriffe...

Wenn man sleep_mode() nimmt, ja, weil das ja das Äquivalent zu
1
  sleep_enable();
2
  sleep_cpu();
3
  sleep_disable();

ist. Wenn man jedoch auf die (eigentlich empfohlene) Abfolge verzichtet 
und das SE-Bit immer gesetzt lässt:
1
  sleep_enable();
2
3
  while("awake")
4
    sleep_cpu();

dann ist das ja nur ein inline asm für den SLEEP-Befehl, der sich 
natürlich nicht weiter um Register kümmert.

von Thomas E. (thomase)


Lesenswert?

Niklas G. schrieb:
> Dafür kann man hier keinen Power Down Modus nutzen; wenn man Interrupts
> nimmt, kann man in der while-Schleife einen solchen aktivieren um
> Energie zu sparen.

Guter Einwand. Dumm nur, daß der Timer dann nicht läuft.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Thomas E. schrieb:
> Guter Einwand. Dumm nur, daß der Timer dann nicht läuft.

Kommt auf den konkreten Modus an... Im am wenigsten sparsamen Modus 
("Idle"?) ist die Peripherie noch komplett an, nur der Prozessor ist 
aus, der ja aber typischerweise der größte Verbraucher ist.

von Thomas E. (thomase)


Lesenswert?

Niklas G. schrieb:
> Kommt auf den konkreten Modus an... Im am wenigsten sparsamen Modus
> ("Idle"?

Vorhin wolltest du noch Power Down.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Thomas E. schrieb:
> Vorhin wolltest du noch Power Down.

Ich meinte damit allgemein "einen der Sparmodi", nicht konkret den einen 
"Power Down" Mode. Habe nicht genau im Kopf welcher beim AVR jetzt was 
macht.

von Thomas E. (thomase)


Lesenswert?

Niklas G. schrieb:
> Ich meinte damit allgemein "einen der Sparmodi",

Dann schreib das auch. Das heißt Sleep Mode. Sind wir hier bei 
gutefrage.net?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Thomas E. schrieb:
> Dann schreib das auch. Das heißt Sleep Mode. Sind wir hier bei
> gutefrage.net?

Verzeih dass ich nicht jeden Controller-spezifischen Begriff auswendig 
weiß. Die Grundaussage ist das was zählt.

von Thomas E. (thomase)


Lesenswert?

Niklas G. schrieb:
> Verzeih dass ich nicht jeden Controller-spezifischen Begriff auswendig
> weiß. Die Grundaussage ist das was zählt.

Nein, das heißt immer Sleep Mode.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Thomas E. schrieb:
> Nein, das heißt immer Sleep Mode.

Bei den STM32F103 heißt das "Low-power modes". "Sleep mode" ist beim 
STM32F103 das was beim AVR der "Idle" ist.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Bernd K. schrieb:
> Also wenn lesbar dann so:
>
> while ("my guitar gently weeps");

Nein.
Entweder 1 oder true.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter D. schrieb:
> Bernd K. schrieb:
>> Also wenn lesbar dann so:
>>
>> while ("my guitar gently weeps");
>
> Nein.
> Entweder 1 oder true.

Humordetektor kaputt?

Peter, du solltest doch nun wirklich alt genug sein, um den 
entsprechenden Beatles-Titel noch zu kennen …

von Ingo L. (corrtexx)


Lesenswert?

egberto schrieb:
> Wenn das mal richtig läuft, kannst du den kompletten Code ja unter
> "Fahrzeugelektronik" Thema E-Bike Tuning posten ;-)
Funktioniert doch, ich habe die CPU jetzt auf 300kHz laufen, damit 
schaffe ich 2kHz Timerinterrupt.
1
int main ( void )
2
{
3
  _delay_ms( 100 );
4
  
5
  CLKPR = (1<<CLKPCE);
6
  CLKPR = (1<<CLKPS2);    // /16
7
  
8
  OSCCAL = 0x63;
9
  // Pulse Output
10
  PULSE_HIGH();
11
  PULSE_DDR |= (1<<PULSE_PIN);
12
  
13
  // Disable AD-Comp
14
  ACSR |= (1<<ACD);
15
  
16
  // Unused Pin low
17
  DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB4);
18
  PORTB &= ~( (1<<PB2) | (1<<PB3) | (1<<PB4) );
19
  
20
  // Setup AVR
21
  OCR0A = 17;
22
  TCCR0A |= (1<<WGM01);      // CTC
23
  TCCR0B |= (1<<CS01);      // Prescaler = 1
24
  
25
  // External Interrupt
26
  PORTB |= (1<<PB1);          // internal Pullup enable
27
  MCUCR |= (1<<ISC01);        // Trigger on falling edge
28
  CLEAR_SENSOR_FLAG();
29
30
  
31
    /* Nice weather... */
32
    while ( "Cycling" ){
33
    if ( TIFR0 & (1<<OCF0A) ){
34
      #if DEBUG_MODE == 1
35
        PULSE_HIGH();
36
      #endif
37
      
38
      // Clear TimerFlag    
39
      TIFR0 |= (1<<OCF0A);
40
  
41
      // Nullerkennung
42
      if ( Timeout ) Timeout--;
43
44
      // Impuls Erfassung
45
      TimeCounter++;
46
  
47
      if ( SENSOR_TRIGGERD ){
48
        Timeout = ZERO_TIME_DETECT;
49
        CLEAR_SENSOR_FLAG();
50
        RoundTrip[NEW] = TimeCounter;
51
        TimeDifference = RoundTrip[NEW] - RoundTrip[OLD];
52
        RoundTrip[OLD] = RoundTrip[NEW];
53
      }
54
55
      // Impuls Ausgabe
56
      if ( TimeDifference < PULSE_PERIOD_MIN_MS ){ // abgeregelt
57
        TunedOutputPeriod = PULSE_PERIOD_MIN_MS;
58
      }else{// unmanipuliert
59
        TunedOutputPeriod = TimeDifference;
60
      }
61
  
62
      if ( TunedOutputPeriod > PULSE_PERIOD_MAX_MS ) TunedOutputPeriod = PULSE_PERIOD_MAX_MS;
63
  
64
      if ( Pulsegenerator >= TunedOutputPeriod ) Pulsegenerator = 0;
65
      else Pulsegenerator++;
66
      
67
      #if DEBUG_MODE == OFF
68
        if ( Pulsegenerator < PULSE_DURATION_MS && Timeout ) PULSE_LOW();
69
        else PULSE_HIGH();
70
      #elif DEBUG_MODE == ON
71
        if ( Pulsegenerator < PULSE_DURATION_MS && Timeout )PORTB &= ~(1<<PB1);
72
        else PORTB |= (1<<PB1); 
73
        PULSE_LOW();
74
      #endif
75
    }
76
  }
77
}

: Bearbeitet durch User
von Egberto (Gast)


Lesenswert?

Na so richtig komplett ist es ja nun nicht.....trotzdem vielen Dank.

von Ingo L. (corrtexx)


Lesenswert?

Egberto schrieb:
> Na so richtig komplett ist es ja nun nicht.....trotzdem vielen
> Dank.
Richtig, das hier fehlt noch:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
5
#define TIMEBASE_1MS      TIM0_COMPA_vect
6
#define PULSE_DDR        DDRB
7
#define PULSE_PORT        PORTB
8
#define PULSE_PIN        PB0
9
#define PULSE_LOW()        (PULSE_PORT &= ~(1<<PULSE_PIN))
10
#define PULSE_HIGH()      (PULSE_PORT |= (1<<PULSE_PIN))
11
12
#define INTERRUPT_FREQ_KHZ    2
13
14
#define PULSE_PERIOD_MIN_MS    359 * INTERRUPT_FREQ_KHZ    // 22km/h
15
#define PULSE_PERIOD_MAX_MS    7898 * INTERRUPT_FREQ_KHZ    // 1km/h
16
#define PULSE_DURATION_MS    2 * INTERRUPT_FREQ_KHZ
17
18
#define ZERO_TIME_DETECT    8000*INTERRUPT_FREQ_KHZ
19
20
#define SENSOR_TRIGGERD      (GIFR & (1<<INTF0))
21
#define CLEAR_SENSOR_FLAG()    (GIFR |= (1<<INTF0))
22
23
#define NEW            1
24
#define OLD            0
25
26
#define ON            1
27
#define OFF            0
28
29
#define DEBUG_MODE        OFF
30
31
static uint16_t TimeCounter = 0;
32
static uint16_t RoundTrip[2] = {0,0};
33
static uint16_t TimeDifference = PULSE_PERIOD_MAX_MS;
34
static uint16_t Pulsegenerator = UINT16_MAX;
35
static uint16_t TunedOutputPeriod = PULSE_PERIOD_MAX_MS;
36
static uint16_t Timeout = ZERO_TIME_DETECT;

von egberto (Gast)


Lesenswert?

Vielen Dank.

Nur für mein Verständnis...eine (leere) Interruproutine für den ext. 
Interrupt braucht man nicht?

Debouncing (oder ist da ein Hallsensor dran)?

Grüße,

egberto

von Ingo L. (corrtexx)


Lesenswert?

egberto schrieb:
> Nur für mein Verständnis...eine (leere) Interruproutine für den ext.
> Interrupt braucht man nicht?
Nicht, wenn man sich mit einem Fehler von maximal 1ms in der Umlaufzeit 
zufrieden gibt.

egberto schrieb:
> Debouncing (oder ist da ein Hallsensor dran)?
Gut das du es sagst, ein Reed-Kontakt prellt natürlich auch... Bau ich 
gleich mal ein

von Dennis Restle (Gast)


Lesenswert?

Der Code in der ISR hat den Vorteil, dass er immer exakt x Mikrosekunden 
nach dem Bit stattfindet. Bei einem Polling hast du einen Jitter von 
mehreren Taktzyklen.

von Ingo L. (corrtexx)


Lesenswert?

Dennis Restle schrieb:
> Der Code in der ISR hat den Vorteil, dass er immer exakt x Mikrosekunden
> nach dem Bit stattfindet. Bei einem Polling hast du einen Jitter von
> mehreren Taktzyklen.
Der aber bei einer Zeitauflösung von 500µs und einer 
Ausführungsgeschwindigkeit von 3 1/3µs pro Takt nicht auffällt...
Hier die Entprellte Version:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
5
#define TIMEBASE_1MS      TIM0_COMPA_vect
6
#define PULSE_DDR        DDRB
7
#define PULSE_PORT        PORTB
8
#define PULSE_PIN        PB0
9
#define PULSE_LOW()        (PULSE_PORT &= ~(1<<PULSE_PIN))
10
#define PULSE_HIGH()      (PULSE_PORT |= (1<<PULSE_PIN))
11
12
#define INTERRUPT_FREQ_KHZ    2
13
14
#define PULSE_PERIOD_MIN_MS    359 * INTERRUPT_FREQ_KHZ    // 22km/h
15
#define PULSE_PERIOD_MAX_MS    7898 * INTERRUPT_FREQ_KHZ    // 1km/h
16
#define PULSE_DURATION_MS    2 * INTERRUPT_FREQ_KHZ
17
18
#define ZERO_TIME_DETECT    8000*INTERRUPT_FREQ_KHZ
19
20
#define SENSOR_TRIGGERD      (GIFR & (1<<INTF0))
21
#define CLEAR_SENSOR_FLAG()    (GIFR |= (1<<INTF0))
22
23
#define NEW            1
24
#define OLD            0
25
26
#define ON            1
27
#define OFF            0
28
29
#define DEBOUNCE_TIME_MS    100 * INTERRUPT_FREQ_KHZ  
30
31
#define DEBUG_MODE        OFF
32
33
static uint16_t TimeCounter = 0;
34
static uint16_t RoundTrip[2] = {0,0};
35
static uint16_t TimeDifference = PULSE_PERIOD_MAX_MS;
36
static uint16_t Pulsegenerator = UINT16_MAX;
37
static uint16_t TunedOutputPeriod = PULSE_PERIOD_MAX_MS;
38
static uint16_t Timeout = ZERO_TIME_DETECT;
39
static uint8_t Debounce = DEBOUNCE_TIME_MS;
40
41
int main ( void )
42
{
43
  _delay_ms( 100 );
44
  
45
  CLKPR = (1<<CLKPCE);
46
  CLKPR = (1<<CLKPS2);    // /16
47
  
48
  OSCCAL = 0x63;
49
  // Pulse Output
50
  PULSE_HIGH();
51
  PULSE_DDR |= (1<<PULSE_PIN);
52
  
53
  // Disable AD-Comp
54
  ACSR |= (1<<ACD);
55
  
56
  // Unused Pin low
57
  DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB4);
58
  PORTB &= ~( (1<<PB2) | (1<<PB3) | (1<<PB4) );
59
  
60
  // Setup AVR
61
  OCR0A = 17;
62
  TCCR0A |= (1<<WGM01);      // CTC
63
  TCCR0B |= (1<<CS01);      // Prescaler = 8
64
  
65
  // External Interrupt
66
  PORTB |= (1<<PB1);          // internal Pullup enable
67
  MCUCR |= (1<<ISC01);        // Trigger on falling edge
68
  CLEAR_SENSOR_FLAG();
69
70
  
71
    /* Nice weather... */
72
    while ( "Cycling" ){
73
    if ( TIFR0 & (1<<OCF0A) ){
74
      #if DEBUG_MODE == 1
75
        PULSE_HIGH();
76
      #endif
77
      
78
      if ( Debounce ) Debounce--;
79
      if ( Debounce == 1 ) CLEAR_SENSOR_FLAG();
80
      
81
      // Clear TimerFlag    
82
      TIFR0 |= (1<<OCF0A);
83
  
84
      // Nullerkennung
85
      if ( Timeout ) Timeout--;
86
87
      // Impuls Erfassung
88
      TimeCounter++;
89
  
90
      if ( SENSOR_TRIGGERD && !Debounce ){
91
        Timeout = ZERO_TIME_DETECT;
92
        Debounce = DEBOUNCE_TIME_MS;
93
        RoundTrip[NEW] = TimeCounter;
94
        TimeDifference = RoundTrip[NEW] - RoundTrip[OLD];
95
        RoundTrip[OLD] = RoundTrip[NEW];
96
      }
97
98
      // Impuls Ausgabe
99
      if ( TimeDifference < PULSE_PERIOD_MIN_MS ){ // abgeregelt
100
        TunedOutputPeriod = PULSE_PERIOD_MIN_MS;
101
      }else{// unmanipuliert
102
        TunedOutputPeriod = TimeDifference;
103
      }
104
  
105
      if ( TunedOutputPeriod > PULSE_PERIOD_MAX_MS ) TunedOutputPeriod = PULSE_PERIOD_MAX_MS;
106
  
107
      if ( Pulsegenerator >= TunedOutputPeriod ) Pulsegenerator = 0;
108
      else Pulsegenerator++;
109
      
110
      #if DEBUG_MODE == OFF
111
        if ( Pulsegenerator < PULSE_DURATION_MS && Timeout ) PULSE_LOW();
112
        else PULSE_HIGH();
113
      #elif DEBUG_MODE == ON
114
        if ( Pulsegenerator < PULSE_DURATION_MS && Timeout )PORTB &= ~(1<<PB1);
115
        else PORTB |= (1<<PB1); 
116
        PULSE_LOW();
117
      #endif
118
    }
119
  }
120
}

von egberto (Gast)


Lesenswert?

mir ging es nur darum, ob da nicht ein zusätzliches

EMPTY_INTERRUPT(INT0_vect);

sauberer wäre.

Grüße,

egberto

von Ingo L. (corrtexx)


Lesenswert?

egberto schrieb:
> mir ging es nur darum, ob da nicht ein zusätzliches
>
> EMPTY_INTERRUPT(INT0_vect);
>
> sauberer wäre.
Wozu denn?

von egberto (Gast)


Lesenswert?

Nach meinem Verständnis versucht der Mikrocontroller bei Interrupt doch 
über den entsprechenden Vector die zugehörige Routine anzuspringen - 
oder ist das nicht immer so?

von Ingo L. (corrtexx)


Lesenswert?

egberto schrieb:
> Nach meinem Verständnis versucht der Mikrocontroller bei Interrupt doch
> über den entsprechenden Vector die zugehörige Routine anzuspringen -
> oder ist das nicht immer so?
Wenn man ihm das sagt ( hier wäre es: GIMSK |= (1<<INT0) ), dann schon. 
Da ich das aber nicht mache, benötige ich auch die dazugehörige ISR 
nicht...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Er hat ja nun aber gar keinen Interrupt mehr aktiviert.

von Ingo L. (corrtexx)


Lesenswert?

Jörg W. schrieb:
> Er hat ja nun aber gar keinen Interrupt mehr aktiviert.
Schneller ;)

von egberto (Gast)


Lesenswert?

ah ja, die Codeänderung hatte ich nicht beachtet....

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.