Interupt bin am Verzweifeln

Gast #442791
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
Gast #442792
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 :)
Gast #442802
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
Gast #442808
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
Gast #442817
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.
Gast #442818
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
Gast #442827
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
Gast #442828
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
Gast #442843
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
Gast #442851
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 :)
Gast #442854
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

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