Forum: Mikrocontroller und Digitale Elektronik Variablenwert geht nach verlassen der ISR verloren


von wuddy (Gast)


Lesenswert?

Also ersteinmal vorweg. Ich programmiere einen MPSF2619.
In diesem Programm wird eine ISR nach Timerüberlauf aufgerufen. In diese 
wird der AD Wandler gestartet und der aktuelle AD Wert in ein Array 
geschrieben. Dies darf allerdings nicht öfters wie 60-mal geschehen. 
Danach soll das "komplette" Programm beendet werden.
Soweit klappt auch alles, bis auf das sich der Zählwert der Variable 
jedesmal auf Null setzt wenn ich die ISR aufrufe. Habe die Zählvariable 
schon global als static definiert.
Das seltsame an der Sache ist, das es im Simulator funktioniert aber auf 
dem Prozesseor nicht.

Hoffe die Angaben sind ausreichend um mich bei meinem Problem zu 
unterstützen.

von Johannes M. (johnny-m)


Lesenswert?

Ist die Variable auch volatile deklariert?

von wuddy (Gast)


Lesenswert?

Danke ersteinmal für die schnelle Antwort.

Zwischendurch war sie es kurzzeitig. Die Kombination aus static und 
volatile habe ich allerdings noch nicht getestet.

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

entweder in der funktion static definieren wenn nur diese funktion die 
variable benutzt,

oder in main global definieren, dann können alle funktionen darauf 
zugreifen.

global & static weis nicht ob es da nicht  einen nesty gibt und die 
Variable automatisch zurückgesetzt wird?

am besten testroutine und testmain um die routine isoliert zu testen

dann in zielprogramm einbinden

wie wäre es du zeigtest mal so ein testmain mit testroutine. dann könnte 
jemand dein vorgehen auf schlüssigkeit oder fehler prüfen.

von wuddy (Gast)


Lesenswert?

Ok hier ist mein eher schlecht als recht geschriebens Testprog.


#include "msp430x26x.h"
#include "main.h"

void zaehl ( )
{
  anz++;
 // while(1);

}

void main ()
{
  WDTCTL = WDTPW + WDTHOLD;
  P1DIR |=0x01;
  BCSCTL1 |= XTS;
  BCSCTL3 |= LFXT1S_3;
  BCSCTL3 &= ~XCAP0;
   //TimerA_Init
  TACCTL0 = CCIE;                        //Capture/compate Int enable
  TACCR0 =50000;                          //11kHz
  TACTL = TASSEL_2 + MC_2 + ID_0 +TAIE;    //ACLK, divided 1, Continuous 
mode, Int enable

  TACTL |= MC1;                          //Timer starten

  //ADC12_Init
  ADC12CTL0 = ADC12ON;                  //AD Wandler wird eingeschaltet
  ADC12CTL1 = SHS_0 + SHP + ADC12DIV_0 + ADC12SSEL_2 + CONSEQ_0; 
//sampling Time, Clock divider=1, single conversion
  ADC12MCTL0 = SREF_0 + INCH_2;    //Channel 2

  //ADC12CTL0 |= ADC12SC + ENC;     //Wandlung starten
  _BIS_SR(GIE);
  while(1);
}

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)

{
    volatile  static int i;


  //pti=&i;
    i++;
    ADC12CTL0 |= ENC + ADC12SC;   //Wandlung starten
    //TACTL |= MC1;  //Timer starten
    P1OUT ^= 0x01;
    CCR0 +=50000;
    array[i] = ADC12MEM0;


    if(i ==60)
    { zaehl();}
    //zaehl();



}

von Johannes M. (johnny-m)


Lesenswert?

Du hast doch erzählt, die Variable sei global! In Deinem Programm ist 
sie es aber gar nicht (Dein Programm enthält keine einzige globale 
Variable)! volatile macht auch nur bei globalen Variablen überhaupt 
Sinn.

Vielleicht solltest Du Dich mal über die Unterschiede von globalen und 
funktionslokalen Variablen erkundigen...

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


Lesenswert?

Was soll das Programm tun?

'i' wird nie zurückgesetzt, und zusammen mit 'array[i] = ADC12MEM0' gibt 
das dann einen amoklaufenden Pointer.

Zudem wird 'anz' nur einmal hochgezählt (und nirgends deklariert).

von wuddy (Gast)


Lesenswert?

@ Johannes M.:
Also der Unterschied zwischen Global und lokal ist mir bekannt. Hatte 
das kurz vorm posten nochmal geändert.Sorry für die Verwirrung.

@Lothar Miller:
Der Sinn und Zweck sei erst einmal dahingestellt. Mir geht es 
Hauptsächlich darum i nach verlassen der ISR zu erhalten. Und im 
Simulator tut es ja auch. Nur wenn ich den FET Debugger nutzesetzt er i 
immer auf Null sobald er die ISR betritt.

von wuddy (Gast)


Lesenswert?

jetzt müsste alles draussen sein, das für Verwirrung sorgen könnte.
in der Header wird lediglich das Array deklariert und eventuell spätere 
Variablen.


#include "msp430x26x.h"
#include "main.h"

volatile int i;

/*void zaehl ( )
{
  anz++;
 // while(1);

}*/

void main ()
{
  WDTCTL = WDTPW + WDTHOLD;
  P1DIR |=0x01;
  BCSCTL1 |= XTS;
  BCSCTL3 |= LFXT1S_3;
  BCSCTL3 &= ~XCAP0;
   //TimerA_Init
  TACCTL0 = CCIE;                        //Capture/compate Int enable
  TACCR0 =0xF400;                          //11kHz
  TACTL = TASSEL_2 + MC_2 + ID_0 +TAIE;    //ACLK, divided 1, Continuous 
mode, Int enable

  TACTL |= MC1;                          //Timer starten

  //ADC12_Init
  ADC12CTL0 = ADC12ON;                  //AD Wandler wird eingeschaltet
  ADC12CTL1 = SHS_0 + SHP + ADC12DIV_0 + ADC12SSEL_2 + CONSEQ_0; 
//sampling Time, Clock divider=1, single conversion
  ADC12MCTL0 = SREF_0 + INCH_2;    //Channel 2

  //ADC12CTL0 |= ADC12SC + ENC;     //Wandlung starten
  _BIS_SR(GIE);
  while(1);
}



#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)

{


  //pti=&i;
    i++;
    ADC12CTL0 |= ENC + ADC12SC;   //Wandlung starten
    //TACTL |= MC1;  //Timer starten
    P1OUT ^= 0x01;
    CCR0 +=0xF400;
    array[i] = ADC12MEM0;


    if(i ==60)
    { i=0;
      }
    //zaehl();



}

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

>>>
....
#include "main.h"

volatile int i;

/*void zaehl ( )
.....
>>>


so bleibt i  aus main für deine ISR unsichtbar und wird lokal neu 
deklariert (automatisch)

 enweder:

>>>
....
#include "main.h"

global int i;

/*void zaehl ( )
.....
>>>


oder:

>>>
....

#include "msp430x26x.h"
#include "main.h"

void main ()
.....


....

 #pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)

{

static int i;
  pti=&i;
    i++;
    ADC12CTL0 |= ENC + ADC12SC;   //Wandlung starten
    //TACTL |= MC1;  //Timer starten
    P1OUT ^= 0x01;
    CCR0 +=0xF400;
    array[i] = ADC12MEM0;


    if(i ==60)
    { i=0;
      }
  zaehl();

}
>>>

von wuddy (Gast)


Lesenswert?

Also ich habe mich für die zweite variante entschieden und noch den 
Zeiger entfernt, da dieser keinerlei Funktion hat.

 #pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)

{

static int i;
    i++;
    ADC12CTL0 |= ENC + ADC12SC;   //Wandlung starten
    //TACTL |= MC1;  //Timer starten
    P1OUT ^= 0x01;
    CCR0 +=0xF400;
    array[i] = ADC12MEM0;


    if(i ==60)
    { i=0;
      }
  zaehl();

}
Ausser in der ISR kommt mein i jetzt nirgens mehr vor aber es will 
dennoch nicht.

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

weil die Routine nicht wieder gestartet wird ,

du hast den timerstart noch auskommentiert, so wird

von wuddy (Gast)


Lesenswert?

OK habs hinbekommen jetzt tut es was es soll, wobei mir die lösung nicht 
ganz klar ist. hab eig nur die Abfrage auf 60 in den main teil genommen.

static int i;

void main (void)  {

  if(i==0){

 P1DIR |=0x01;
      //TimerA_Init
  TACCTL0 = CCIE;                        //Capture/compate Int enable
  TACCR0 =0x3FFF;                          //11kHz
  //*************Achtung, nur zu Testzwecken TASSEL_2*************
  TACTL = TASSEL_2 + MC_2 + ID_0 +TAIE;    //ACLK, divided 1, Continuous 
mode, Int enable
  TACTL |= MC1;                          //Timer starten

  //ADC12_Init
  ADC12CTL0 = ADC12ON;                  //AD Wandler wird eingeschaltet
  ADC12CTL1 = SHS_0 + SHP + ADC12DIV_0 + ADC12SSEL_2 + CONSEQ_0; 
//sampling Time, Clock divider=1, single conversion
  ADC12MCTL0 = SREF_0 + INCH_2;  }  //Channel 2

  //ADC12CTL0 |= ADC12SC + ENC;     //Wandlung starten
  _BIS_SR(GIE);
  while(1);
}

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)

{

  ADC12CTL0 |= ENC + ADC12SC;   //Wandlung starten
  //TACTL |= MC1;  //Timer starten
  P1OUT ^= 0x01;
  CCR0 += 0x3FFF;
  i++;
  main();
}

wenn mir jetzt noch jemand erklären kann was da jetzt genau der 
Unterschied ist, ist mein Tag gerettet.

von wuddy (Gast)


Lesenswert?

naja das mit der Abfrage auf 60 fehlt noch :D

von Stefan B. (stefan) Benutzerseite


Lesenswert?

wuddy wrote:

> wenn mir jetzt noch jemand erklären kann was da jetzt genau der
> Unterschied ist, ist mein Tag gerettet.

Dein letzter Code ist von hinten durchs Knie in die Brust geschossen. Es 
mag eine Zeit lang funktionieren, aber 99% der Programmierer schütteln 
sich.

main() wieder innerhalb der ISR aufrufen ist IMHO ein No-Go. Du erzeugst 
damit eine Rekursion, die nie aufgelöst wird und die dir wahrscheinlich 
mit einem Stacküberlauf als Programmfehler endet.

Auch wird erste Interrupt formal gesehen nie verlassen, da die ISR nicht 
verlassen wird. Der Programmzeiger kommt nicht zum } hinter dem dortigen 
main(). (Ich habe hierbei nicht geprüft, ob _BIS_SR(GIE); den aktuellen 
Interrupt löscht)

Ein "normaler" Programmierer würde in main() den Timer initialisieren 
und starten und dann in eine endlose Hauptarbeitsschleife anstossen.

In der ISR würde ggf. eine Aktion ausgeführt (z.B. Hochzählen einer 
globalen, volatilen Variable) und ggf. der Timer neu initialisiert.

von wuddy (Gast)


Lesenswert?

Hm..ja ok, das ist wirklich ziemlich konfus gemacht. Aber wie sieht es 
aus wenn das ganz selber als Unterprogramm zu realisieren ist und nach 
erreichen der 60 Werte ins eigentliche Hauptprogramm gesprungen werden 
soll?

von wuddy (Gast)


Lesenswert?

Kann es sein das der Fehler wo anders liegt. Folgendes Szenario:

Ich debugge das ganze im Stepbetrieb. Komme bis zur while() und warte 
dann dort bis der Timer die gewünschte Zahl erreicht hat.Von Hand stelle 
ich dann das TAR-Reg auf den gewünschten Wert. Infolgedessen wird 
Interrupt ausgelöst und Sprung in die ISR. Soweit, sogut. Weiter im 
Stepbetrieb bis zur letzten Klammer der ISR }. Nach Ausführen der 
Klammer springt der Debugger in RUN und es kommt kein INT mehr. Erst 
wenn ich ihn stoppe und von Hand erneut einen INT auslöse.
Da ist das nicht ganz nachvollziehen kann habe ich diese ganze "main" - 
Springerrei eingebau.

von Bereits F. (Firma: D.ade) (bereitsfort)


Lesenswert?

main() // das Hauptprogramm

Ist üblicherweise mit warten und auf Ereignisse und Aufrufen von 
Unterprogrammen (Funktionen und Routinen) beschäftigt, welche ihrerseits 
nach abarbeiten ihres jobs ihren status an main zurückmelden.
ISR sind ereignisbasierte Routinen, welche dazu dienen ein zeitlich 
nicht vorhersehbares Ereignis zu erfassen oder eben bei timer IRQ 
regelmäsig das laufende Programm zu unterbrechen um notwendige 
Aktualisierungen anzustoßen. Üblicher weise setzen sie ein Flag damit 
das Hauptpprgram eine passende Subroutine aufrufen kann. Diese erledigt 
dann den eigentlichen Job und kehrt anschließend nach main zurück.

von wuddy (Gast)


Lesenswert?

Wäre es möglich das der TimerA falsch initialisiert ist und so die 
Interrupts nicht richtig auslösen?
TimerA soll im Compare Mode und Continuous mode laufen. Grundsätzlich 
ist mir µC Programmieren bekannt da ich schon mit PIC und ARM gearbeitet 
hab. Mit MSP habe ich allerdings erst seit 3 Wochen zu tun.

von wuddy (Gast)


Lesenswert?

So jetzt nochmal mein Ursprungsprogramm das ich gestern geschrieben 
hatte und dachte das ist am logischsten:

#include "msp430x26x.h"
#include "main.h"



static  int i;

void main (void)  {

  //if(i==0){
 WDTCTL = WDTPW + WDTHOLD;
 P1DIR |=0x01;
      //TimerA_Init
  TACCTL0 = CCIE;                        //Capture/compate Int enable
  TACCR0 =50000;                          //11kHz
  //*************Achtung, nur zu Testzwecken TASSEL_2*************
  TACTL = TASSEL_2 + MC_2 + ID_0 +TAIE;    //ACLK, divided 1, Continuous 
mode, Int enable
  TACTL |= MC1;                          //Timer starten

  //ADC12_Init
  ADC12CTL0 = ADC12ON;                  //AD Wandler wird eingeschaltet
  ADC12CTL1 = SHS_0 + SHP + ADC12DIV_0 + ADC12SSEL_2 + CONSEQ_0; 
//sampling Time, Clock divider=1, single conversion
  ADC12MCTL0 = SREF_0 + INCH_2;  //}  //Channel 2

  //ADC12CTL0 |= ADC12SC + ENC;     //Wandlung starten
  _BIS_SR(GIE);
  while(1);
}

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)

{

  ADC12CTL0 |= ENC + ADC12SC;   //Wandlung starten
  //TACTL |= MC1;  //Timer starten
  P1OUT ^= 0x01;
  CCR0 += 50000;
  i++;
}

nach dem tausendsten Debuggversuch und einiger Breakpoints stimmt alles. 
Oder gibt es noch was dran auszusetzen?

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


Lesenswert?

> static  int i;
1
volatile int i;
Sonst kann es sein, dass der Compiler in anderen Routinen nicht erkennt, 
dass i ausserhalb geändert wird.

Denn das:
1
  while(1);
wird vermutlich auch noch anders?


BTW:
mit [/c] und [c] kann man C-Code schön darstellen.
Siehe Formatierung in der grauen Box um das Eingabefeld.

von wuddy (Gast)


Lesenswert?

Ja das
1
while()
 wird auch noch anders. Die eigentliche Arbeit kommt jetzt erst noch :/ 
Das eben war nur Vorgeplänkel. Na toll und das hat so Kopfzerbrechen 
bereitet.
Danke nochmal für die schnelle und ausführliche Hilfe!

von wuddy (Gast)


Lesenswert?

Ich habe das Programm am Freitag noch einmal auf Herz und Nieren 
getestet und debugged und das Problem besteht nachwievor. Mir ist aber 
beim debuggen aufgefallen, dass er nach der ISR nicht in die while geht 
und wartet sondern die main komplett neu durchgeht.
1
void main (void)  {
2
  
3
  //if(i==0){ 
4
  WDTCTL = WDTPW + WDTHOLD; 
5
  P1DIR |=0x01;
6
      //TimerA_Init
7
  TACCTL0 = CCIE;                        //Capture/compate Int enable
8
  TACCR0 =50000;                          //11kHz
9
  //*************Achtung, nur zu Testzwecken TASSEL_2*************
10
  TACTL = TASSEL_2 + MC_2 + ID_0 +TAIE;    //ACLK, divided 1, Continuous mode, Int enable
11
  //TACTL |= MC1;                          //Timer starten
12
  
13
  //ADC12_Init
14
  ADC12CTL0 = ADC12ON;                  //AD Wandler wird eingeschaltet
15
  ADC12CTL1 = SHS_0 + SHP + ADC12DIV_0 + ADC12SSEL_2 + CONSEQ_0;    //sampling Time, Clock divider=1, single conversion
16
  ADC12MCTL0 = SREF_0 + INCH_2;  //}  //Channel 2 
17
18
  //ADC12CTL0 |= ADC12SC + ENC;     //Wandlung starten
19
  _BIS_SR(GIE);
20
  while(1);
21
22
}
23
24
#pragma vector=TIMERA0_VECTOR
25
__interrupt void Timer_A (void)
26
 
27
{
28
  static int a;
29
  ADC12CTL0 |= ENC + ADC12SC;   //Wandlung starten
30
  TACTL |= MC1;  //Timer starten
31
  P1OUT ^= 0x01;
32
  CCR0 += 50000;
33
  a++;
34
}

Mir ist jetzt allerdings nicht mehr so ganz klar wie und wo ich die 
zählvariable definieren soll, damit beide Funktionen drauf zugreifen 
können und sie auch ändern können.

von wuddy (Gast)


Lesenswert?

Kann es sein das der Timer falsch initiallisiert ist? Denn wenn ich mir 
das TAR im Debugger anschaue macht das komische Dinge.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Mir ist jetzt allerdings nicht mehr so ganz klar wie und wo ich die
> zählvariable definieren soll, damit beide Funktionen drauf zugreifen
> können und sie auch ändern können.

Die Zählvariable scheint Dein 'a' zu sein. Anstelle es in der ISR als 
static zu deklarieren, musst Du es nur außerhalb der ISR und außerhalb 
von main als volatile deklarieren.

> Mir ist aber beim debuggen aufgefallen, dass er nach der ISR
> nicht in die while geht und wartet sondern die main komplett
> neu durchgeht.

Dann geht da wohl irgendwas schief.

>   TACTL |= MC1;  //Timer starten

Bist Du Dir sicher, daß diese Zeile in die Timer-ISR gehört?

>   CCR0 += 50000;

Willst Du das? Nicht TACCR0?

von wuddy (Gast)


Lesenswert?

Beim dem
1
TACTL |= MC1;
  war ich mir nicht sicher.

Ach und ich dachte TACCR0 und CCR0 seien das gleiche Register da in der 
Header ja steht
1
#define CCR0                TACCR0

von wuddy (Gast)


Lesenswert?

Habe jetzt festgestellt das der Interrupt auslöst sobalt der Wert im 
Compare Reg erreicht ist, was ja auch gewünscht. Aber sobald das TAR von 
0xFFFF nach 0x0000 wechseln sollte Schwachsinn passiert und nach 
unbestimmter Zeit wieder die main von vorn aufgerufen wird.

von wuddy (Gast)


Lesenswert?

OK jetzt weiß ich wo der Fehler ist. Sobald ein Überluaf von FFFF->0000 
stattfindet wird ein zweiter, "nicht definierter" Interrupt ausgelöst, 
der den Programmzeiger ins Nirvana zeigen lässt. Anschließend wird die 
main "neugestartet" Allerdings ist mir nicht so ganz klar warum der 
Inhalt der Variablen dann verloren geht. Bestimmt wird einfach alles neu 
initiallisiert, was dann auch die Register zurücksetzt.

Meine Frage wäre jetzt wie ich den zweiten, nicht erwünschten, Interrupt 
abschalte.

von wuddy (Gast)


Lesenswert?

@Lothar Miller:
Was genau meinst du mit Watchdog?

von Guru (Gast)


Lesenswert?

Indem du ihn gar nicht erst einschaltest!

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


Lesenswert?

> Meine Frage wäre jetzt wie ich den zweiten,
> nicht erwünschten, Interrupt abschalte.
Du darfst den nicht einschalten, ich würde auf diese Zeile tippen:
1
  TACTL = TASSEL_2 + MC_2 + ID_0 +TAIE;    //ACLK, divided 1, Continuous mode, Int enable

Probiers doch mal so:
1
  TACTL = TASSEL_2 + MC_2 + ID_0;    //ACLK, divided 1, Continuous mode

> Was genau meinst du mit Watchdog?
Passt schon, du schaltest den korrekt ab.
  WDTCTL = WDTPW + WDTHOLD;

von wuddy (Gast)


Lesenswert?

Hm...ja...OK...auf dem falschen Fuss erwischt. Leider ist mir die 
Funktion des Watchdog nicht ganz geläufig. Weiß nur das das auch eine 
Art Timer ist.
Hab WDTCTL = WDTPW + WDTHOLD jetzt mal auskommentiert aber TAIFG wird 
dennoch gesetzt.

von wuddy (Gast)


Lesenswert?

OK auf den ersten Blick sieht es gut aus, jetzt wird nur ein INT 
ausgelöst.
Will mal versuchen den Fehler zu rekonstruieren.
Durch
1
TACTL = TASSEL_2 + MC_2 + ID_0 +TAIE;
 habe ich alle Interrups freigegeben, also auch den Overflow.

von Christian R. (supachris)


Lesenswert?

TAIE gibt nur den Overflow-Interrupt frei, die CCR-Interrupts sind in 
den passenden TACCTLx Registern zu finden (Bit CCIE). TAIFG wird bei 
Überlauf immer gesetzt, egal, ob der Interrupt freigegeben ist oder 
nicht, TAIE schaltet nur den IRQ zum Interrupt-Controller durch.

Watchdog auskommentieren ist auch schlecht, dann startet dein Programm 
in regelmäßigen Abständen neu. Alle Variablen usw. sind dann natürlich 
weg, weil quasi ein Kaltstart vorgenommen wird. Lass die Zeile mit 
WDTHOLD mal schön drin.

Außerdem nimmst du den falschen Interrupt-Vektor. TIMER_A0 ist nur für 
den Overflow. Die CCR-Interrupts teilen sich den TIMER_A1 Vektor, da 
musst du dann auch das TAIV auswerten, um festzustellen, welcher CCR-Int 
jetzt kam.

Du solltest dich erst mal eingehend mit dem User Guide beschäftigen, da 
steht alles wichtige drin.

von wuddy (Gast)


Lesenswert?

So der Watchdog ist jetzt wieder drin und der Overflow ist "deaktivier". 
Sieht bis jetzt auch gut aus. Das Ding läuft durch und erhöht ständig 
den Wert, so wie es auch soll.

Bedanke mich recht herzlich für die ausführliche und schnelle Hilfe.

von wuddy (Gast)


Lesenswert?

Den Rat mit dem User Guide werd ich mir zur Brust nehmen. Hab es auf die 
gute, alte "learnig by doing" Variante versucht und bin, wie man dem 
Thread entnehmen kann, kläglich gescheitert :D

von Sebastian B. (mircobolle)


Lesenswert?

wuddy wrote:
> OK auf den ersten Blick sieht es gut aus, jetzt wird nur ein INT
> ausgelöst.
> Will mal versuchen den Fehler zu rekonstruieren.
> Durch
1
TACTL = TASSEL_2 + MC_2 + ID_0 +TAIE;
 habe ich alle
> Interrups freigegeben, also auch den Overflow.

Wie wäre es mit einer Interrupt Vektor Tabelle?

Du definierst für jeden aktivierten Interrupt eine ISR.

Aber das sicherste ist, nur die Interrupts zu aktivieren, die man 
wirklich verwenden möchte. Dazu nützt es das Handbuch (Manual) des 
Controllers beim Programmieren zur Hand zu haben. Das erspart viel Ärger 
;-)

Was mir an deinem Code auch noch aufgefallen ist, du verlässt dich beim 
Initialisieren deiner Variablen immer auf den Compiler. Zur Sicherheit 
würde ich aber immer ein
1
 = 0
 schreiben, damit man sicher ist, dass die Variable einen definierten 
Wert hat.

MFG

von wuddy (Gast)


Lesenswert?

Ja ok den Wink mit dem Handbuch habe ich verstanden :)
Das mit dem initialisiren ist schon klar. Das ganze diente nur zu 
Testzwecken. Das eigentliche Programm ist dann ausführlicher und besser 
durchdacht, natürlich auch mit entsprechenden Vorabdefinitionen. Aber 
danke für den Hinweiß, hätte es später dann bestimmt vergessen.

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.