ISR-Routine, Global Variable / Counter Erhöhen

Gast #1179556
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ß
Gast #1179590
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 ?
Gast #1179622
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...
#1179627
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 
...
Gast #1179634
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
}
Gast #1179636
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
#1179668
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 :-)
#1179681
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
  }
Gast #1179693
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ß

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren