Forum: Mikrocontroller und Digitale Elektronik ISR-Routine, Global Variable / Counter Erhöhen


von GreenHorn_ISR (Gast)


Lesenswert?

Hallo uC-Freunde,

leider habe ich im Forum keine Antwort gefunden :-( Daher auf diesem 
Wege.

Ich erhöhe in einer ISR(sie springt auch beim Event an!) immer eine 
globale Variable nach:
1
volatile unsigned int temp=0;
2
3
void main()
4
{
5
//richte ISR ein --> OK
6
while(1);
7
}
8
9
ISR(INT0_vect)
10
{
11
  if (SPI_get_Return_Code_LCD() == MINUS)
12
    {
13
    temp = temp -10;  //Erhöhe
14
                    ausgabe();    //Gebe Wert aus
15
    }  
16
  else
17
    {
18
    temp = temp + 10; //erniedrige
19
                    ausgabe();
20
    }
21
}

Manchmal addiert er bei der Addition, aber manchmal erscheint dann nen 
ganz anderer Wert.. Also z.B. von 230 auf 074 oder so.. Dasselbige bei 
der Subtraktion :-(

volatile will auch nix helfen. Könnt ihr mir helfen, warum der Kollege 
beim AVR-GCC nicht "richtig" summieren und subtrahieren will ? Die 
Ausgabe ist richtig auf der "ausgabe()"

gruß

von Johannes M. (johnny-m)


Lesenswert?

Und was löst den INT0 aus? Doch nicht etwa ein Taster?

von GreenHorn_ISR (Gast)


Lesenswert?

Ne,

mit INT0 wird einfach nur erkannt, dass eine Eingabe auf einem Touch 
erfolgte...

von Johannes M. (johnny-m)


Lesenswert?

GreenHorn_ISR wrote:
> mit INT0 wird einfach nur erkannt, dass eine Eingabe auf einem Touch
> erfolgte...
Wat isn Touch? Sicher, dass es da absolut kein Prellen gibt?

Wie wäre es denn mal mit einer etwas präziseren Ausdrucksweise?

von GreenHorn_ISR (Gast)


Lesenswert?

Hallo Johannes,

ok..entschuldige.Ich versuche mich zu bessern :-)

Habe ein Touchpanel EDIP320-BWLTP am SPI-Port dran hängen. Das generiert 
mir einen LOW-Pegel, wenn Daten (wie z.B. Touchtastendruck!) erzeugt 
wurde. Also ruft er bei "Daten zum abholen" die ISR "auf". Low-Pegel = 
ISR. Habe auf dem Touchpanel eine plus und eine Minustaste. Je nach 
drücken wird dann der Counter temp erhöht oder erniedrigt. Aufffallend 
ist, dass der den bei größer 250 (Var.Wert) erniedrigt. Habe gerade ein 
Oscar dran gehangen, an den INT0. Das sieht sauber aus. Wenn der Pegel 
auf Low geht. War aber ne gute Idee :-)

Ich vermute nen Programmierfehler ?

von Johannes M. (johnny-m)


Lesenswert?

Ausgabefunktionen jedweder Art haben normalerweise nichts in Interrupt 
Handlern verloren.

von GreenHorn_ISR (Gast)


Lesenswert?

Hi,

hast recht. so klein wie möglich halten :-) In der Endsoftware werde ich 
dort nur nen BIt toggeln(StatusBit!).

gruß

von GreenHorn_ISR (Gast)


Lesenswert?

Hi,

habe das nun in die main erstmal verbannt. In dieser ändert sich auch 
nix an dem Verhalten. Was ja auffällig ist, dass ab 250 + 10 = 260 der 
Sprung nach Null kommt. Also hieße das ja das temp als kein Integer 
compiliert wird. Sondern als Character(also max d255). Nur das ist ja 
nicht so....

Hmm...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Immer diese Codefetzen...

Ich biete dir mal zwei Antwortfetzen

Wo stellst im Code du die Probleme fest?
Wird dort vielleicht nur auf das niederwertige Byte geachtet?

von Karl H. (kbuchegg)


Lesenswert?

ALso entweder wird deine ISR öfter angesprungen als du denkst, oder du 
hast irgendwo einen bösen Tippfehler im Programm. Aber ohne Originalcode 
wird man das nicht sagen können. Variablennamen ala i, j, temp, temp2 
sind jedenfalls immer wieder heiße Kandidaten für Scopeprobleme, die man 
gerne übersieht. Soll heißen: es gibt eine globale Variable namens temp 
aber auch eine lokale. Der Programmierer meint eigentlich die globale 
Variable, der Compiler hat aber zuerst die lokale Variable im Scope, etc 
...

von GreenHorn_ISR (Gast)


Lesenswert?

Hallo Jungs und Helfer :-)

eig. darf ich das ja nit hier reinstellen, aber es dient ja der Bildung 
:-)
1
while(1)
2
  {
3
4
    a = (unsigned char)  temp / 10000;          
5
    b = ((unsigned char) temp / 1000) - (a*10000);    
6
    c = ((unsigned char) temp / 100 ) - (a*1000) -(b*10);  
7
    d = ((unsigned char) temp / 10 ) - (a*100) -(b*100)-(c*10);  
8
    e = ((unsigned char) temp / 1 ) - (a*10) -(b*1000)-(c*100);  
9
    show_content(80,50,(a+0x30));
10
    show_content(120,50,(b+0x30));
11
    show_content(160,50,(c+0x30));  
12
    show_content(200,50,(d+0x30));  
13
    show_content(240,50,(e+0x30));  
14
    
15
    
16
  if (STATE_LCD == 1)
17
    {
18
    STATE_LCD=0;
19
    if(SPI_get_Return_Code_LCD() == MINUS)
20
      {
21
      temp = temp -10;
22
      show_content(150,150,(0x2D));
23
      set_Output_I(temp);
24
      }  
25
    else
26
      {
27
      temp = temp + 10;
28
      show_content(150,150,(0x2B));
29
      set_Output_I(temp);    
30
      }
31
    }
32
  }
33
}
34
35
ISR(INT0_vect)
36
{
37
  STATE_LCD ^=1;                    
38
39
}

von GreenHorn_ISR (Gast)


Lesenswert?

Sorry, das war absenden anstatt vorschau... schäm
Also: show_content(..); gibt mir an Stelle X und Y den ASCII Code raus
die a-f filtern mir die einzelnen Dezimalstellen raus.
SPI_get_Return_Code_LCD() liefert mir einen Rückgabewert des Touchpanels

von Karl H. (kbuchegg)


Lesenswert?

>    a = (unsigned char)  temp / 10000;
>    b = ((unsigned char) temp / 1000) - (a*10000);
>    c = ((unsigned char) temp / 100 ) - (a*1000) -(b*10);
>    d = ((unsigned char) temp / 10 ) - (a*100) -(b*100)-(c*10);
>    e = ((unsigned char) temp / 1 ) - (a*10) -(b*1000)-(c*100);



und das du hier temp erst mal nach unsigned char castest, beunruhigt 
dich nicht weiter :-)

von Karl H. (kbuchegg)


Lesenswert?

Diese ganze Sequenz
1
    a = (unsigned char)  temp / 10000;          
2
    b = ((unsigned char) temp / 1000) - (a*10000);    
3
    c = ((unsigned char) temp / 100 ) - (a*1000) -(b*10);  
4
    d = ((unsigned char) temp / 10 ) - (a*100) -(b*100)-(c*10);  
5
    e = ((unsigned char) temp / 1 ) - (a*10) -(b*1000)-(c*100);  
6
    show_content(80,50,(a+0x30));
7
    show_content(120,50,(b+0x30));
8
    show_content(160,50,(c+0x30));  
9
    show_content(200,50,(d+0x30));  
10
    show_content(240,50,(e+0x30));

kannst du ersetzen durch
1
  uint8_t i;
2
  uint16_t outnr;
3
...
4
5
  outnr = temp;
6
  for( i = 0; i < 5; ++i ) {
7
    show_content( 240 - i * 40, 50, outnr % 10 + '0' );
8
    outnr = outnr / 10;
9
  }

von GreenHorn_ISR (Gast)


Lesenswert?

Hallo Jungs,

vielen Dank! So manchmal sieht man den Wald vor lauter Bäumen nicht. 
Dann habe ich mal wieder was dazugelernt. ( C-missstände von mir :-( ) 
Dachte, dass ich dann temp nicht ändere, sondern nur das für z.B a = 
Caste (wollte damit halt die nachkommastellen löschen!)#

Hmm, dann nehme ich wohl doch Modulo ( %). Davon bin ich nie so nen 
Freund...

Danke euch allen und besonders dir, KH Buchenegger!

gruß

von Lutz (Gast)


Lesenswert?

>volatile unsigned int temp=0;
>temp = temp -10;

Quizfrage: Was steht in einer unsigned variable der man(n) Werte < 0 
zuweist (oder genauer: wie wird dieser Wert interpretiert?

von GreenHorn_ISR (Gast)


Lesenswert?

ist ja schon signed int... :-)

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.