Forum: Compiler & IDEs Interupt bin am Verzweifeln


von Björn (Gast)


Lesenswert?

Hallo

ich bin jetzt seit 2 Tagen mit dem Interrupt am kämpfen.
Ich verstehe nur nicht warum er mir entweder Seite 1 oder Seite 2 
anzeigt wenn ich die If Bedingung ändere.
Eigenlich sollte er ja zwischen beidem Toggeln.
Ich nutze WinAVR und einen AT90S2313 mit 4 Mhz

Danke im vorraus
Björn

von Björn (Gast)


Lesenswert?

1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include "lcd.h"
4
#include <avr/interrupt.h>
5
# define F_CPU 4000000UL
6
7
/*
8
** constant definitions
9
*/
10
static const PROGMEM unsigned char copyRightChar[] =
11
{
12
  0x07, 0x08, 0x13, 0x14, 0x14, 0x13, 0x08, 0x07,
13
  0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00
14
};
15
16
volatile unsigned int Counter;
17
volatile unsigned int test=0;
18
19
20
ISR(TIMER0_OVF_vect)       // alle 0.000256 Sekunden / 4 Mhz
21
  {
22
    Counter++;
23
    
24
    if( Counter == 6000 ) 
25
      {
26
        Counter = 0;
27
      }
28
  
29
  
30
  
31
  }
32
  
33
int main(void)
34
{  
35
36
    TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 );    /* Teiler auf CPU/1024 */
37
    TIMSK |= ( 1 << TOIE0 );          //
38
    sei();                    // Alle Interrupts aktiv
39
    
40
    lcd_init(LCD_DISP_ON);            /* Display initialisieren */
41
    
42
    
43
    
44
    if (Counter>=3000)
45
    (
46
    lcd_puts("Seite 1")
47
    
48
    );
49
    
50
    else
51
    (
52
    lcd_puts("Seite 2")
53
    
54
    );
55
        
56
57
 return 0;
58
}

Warum er auch immer nicht die Datei angehängt hat na ja dann halt so :)

von Magnus Müller (Gast)


Lesenswert?

Hast du schon mal an die Möglichkeit gedacht, daß der Controller 
vielleicht nicht mehr aus der lcd_puts() Funktion zurück springt?

Wenn du deine main() durch die folgende main() ersetzt...
1
int main(void)
2
{
3
  TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 );    /* Teiler auf CPU/1024 */
4
  TIMSK |= ( 1 << TOIE0 );          //
5
  sei();                    // Alle Interrupts aktiv
6
7
  lcd_init(LCD_DISP_ON);            /* Display initialisieren */
8
9
  lcd_puts("Seite 1");
10
  lcd_puts("Seite 2");
11
12
  return 0;
13
}

...sollte auf dem Display "Seite 2" erscheinen. Wenn "Seite 1" angezeigt 
wird, stimmt mit deiner lcd_puts() etwas nicht!

Gruß,
Magnetus

von Magnus Müller (Gast)


Lesenswert?

*** AUTSCH ***

Ich sehe heute mal wieder den Wald vor lauter Bäumen nicht... schäm

Du musst natürlich deine if-Abfrage in eine Endlosschleife einbetten, da 
sonst diese Abfrage nur EINMAL durchgeführt wird!

Mach dat mal so:
1
  while(1)
2
  {
3
    if (Counter>=3000)
4
      lcd_puts("Seite 1");
5
    else
6
      lcd_puts("Seite 2");
7
  };

Gruß,
Magnetus

von Björn (Gast)


Lesenswert?

Hallo Magnetus

Danke erstmal dafür.

Aber das ist es leider auch nicht.
Die Displayroutinen sind io. Habe ich schon alles in anderen datein 
ausprobiert.
Ich Weiß halt nur nicht ob mein Problem am Interupt oder an der Abfrage 
Counter <= 3000 liegt.

von Magnus Müller (Gast)


Lesenswert?

...oder so...
1
  while(1)
2
  {
3
    while(Counter>3000);  // gib Seite 1 erst aus wenn Counter <= 3000
4
    lcd_puts("Seite 1");
5
6
    while(Counter<=3000);  // gib Seite 1 erst aus wenn Counter > 3000
7
    lcd_puts("Seite 2");
8
  };

Gruß,
Magnetus

von Magnus Müller (Gast)


Lesenswert?

> Ich Weiß halt nur nicht ob mein Problem am Interupt oder an der Abfrage
> Counter <= 3000 liegt.

siehe meine letzten beiden Postings.

Gruß,
Magnetus

von Björn (Gast)


Lesenswert?

Ach nochwas

main.c:20: warning: `TIMER0_OVF_vect' appears to be a misspelled signal 
handler

hat das was zu sagen?

von Björn (Gast)


Lesenswert?

1
ISR(TIMER0_OVF_vect)       // alle 0.000256 Sekunden / 4 Mhz
2
  {
3
    Counter++;
4
    
5
    if( Counter == 6000 ) 
6
      {
7
        Counter = 0;
8
      }
9
  
10
  
11
  
12
  }
13
  
14
int main(void)
15
{  
16
17
    TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 );    /* Teiler auf CPU/1024 */
18
    TIMSK |= ( 1 << TOIE0 );          //
19
    sei();                    // Alle Interrupts aktiv
20
    
21
    lcd_init(LCD_DISP_ON);            /* Display initialisieren */
22
    
23
    
24
    
25
while(1)
26
  {
27
    while(Counter>3000);  // gib Seite 1 erst aus wenn Counter <= 3000
28
    lcd_puts("Seite 1");
29
30
    while(Counter<=3000);  // gib Seite 1 erst aus wenn Counter > 3000
31
    lcd_puts("Seite 2");
32
  };
33
34
 return 0;
35
}

Hab das mal modifiziert

Er schreibt nur Seite 1

von Magnus Müller (Gast)


Lesenswert?

Björn wrote:
> Ach nochwas
>
> main.c:20: warning: `TIMER0_OVF_vect' appears to be a misspelled signal
> handler
>
> hat das was zu sagen?

Jau... Dein Compiler weiss nicht wirklich was du willst.

Welchen Controller verwendest du? Wenn du einen der folgenden Controller 
verwendest musst du den Namen 'TIMER0_OVF0_vect' verwenden!

AT90S2313, AT90S2323, AT90S2343, ATtiny22, ATtiny26

Gruß,
Magnetus

von Björn (Gast)


Lesenswert?

Ja jetzt verschwindet die Meldung vom compiler aber klappen tut das 
immernoch nicht
Ich verwende ein AT90S2313

von Magnus Müller (Gast)


Lesenswert?

Hast du den Code schon mal mit AVRStudio simuliert?

von Björn (Gast)


Lesenswert?

ne bis jetzt noch nicht

von Magnus Müller (Gast)


Lesenswert?

Dann lass deinen Controller einfach mal 196,608 Sekunden (3Min. 16Sek. 
608ms) laufen. Dann kommt auch deine "Seite 2" aufs Display.

Grund:

mit
1
TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 );    /* Teiler auf CPU/1024 */

wird der Interrupt erst nach 65536µs ausgelöst. Erst nach 3000*65536µs 
wird dann "Seite 2" ausgegeben.

Gruß,
Magnetus

von Björn (Gast)


Lesenswert?

Jetzt wirds klar und es läuft. Vielen Dank

Aber warum ich dachte ich teile den Takt duch 1024 und nicht erst duch 
1024 und nochmal durch 256?

4 Mhz/ 1024 = 3906,25 Hz
3906,25 /256 = 15,258... Hz = 65536µS
?????
jetz bin ich richtig durcheinander :)

von Björn (Gast)


Lesenswert?

Hat sich erledigt ich hab den überlauf vergessen :)

von Magnus Müller (Gast)


Lesenswert?

> Aber warum ich dachte ich teile den Takt duch 1024 und nicht erst duch
> 1024 und nochmal durch 256?
>
> 4 Mhz/ 1024 = 3906,25 Hz
> 3906,25 /256 = 15,258... Hz = 65536µS
> ?????
> jetz bin ich richtig durcheinander :)

- Der Prozessor wird mit 4.000.000Hz getaktet
- Der TIMER0-Prescaler steht auf clk/1024
- Der TIMER0_OVF0 Interrupt tritt auf wenn TIMER0 überläuft
  (nach 256*1024 Takten)

Rechnung:

  ( 1s / 4.000.000Hz )  1024  256 = 0,065536s

Gruß,
Magnetus

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.