mikrocontroller.net

Forum: Compiler & IDEs Interupt bin am Verzweifeln


Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <stdlib.h>
#include <avr/io.h>
#include "lcd.h"
#include <avr/interrupt.h>
# define F_CPU 4000000UL

/*
** constant definitions
*/
static const PROGMEM unsigned char copyRightChar[] =
{
  0x07, 0x08, 0x13, 0x14, 0x14, 0x13, 0x08, 0x07,
  0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00
};

volatile unsigned int Counter;
volatile unsigned int test=0;


ISR(TIMER0_OVF_vect)       // alle 0.000256 Sekunden / 4 Mhz
  {
    Counter++;
    
    if( Counter == 6000 ) 
      {
        Counter = 0;
      }
  
  
  
  }
  
int main(void)
{  

    TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 );    /* Teiler auf CPU/1024 */
    TIMSK |= ( 1 << TOIE0 );          //
    sei();                    // Alle Interrupts aktiv
    
    lcd_init(LCD_DISP_ON);            /* Display initialisieren */
    
    
    
    if (Counter>=3000)
    (
    lcd_puts("Seite 1")
    
    );
    
    else
    (
    lcd_puts("Seite 2")
    
    );
        

 return 0;
}     

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

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...
int main(void)
{
  TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 );    /* Teiler auf CPU/1024 */
  TIMSK |= ( 1 << TOIE0 );          //
  sei();                    // Alle Interrupts aktiv

  lcd_init(LCD_DISP_ON);            /* Display initialisieren */

  lcd_puts("Seite 1");
  lcd_puts("Seite 2");

  return 0;
}

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

Gruß,
Magnetus

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
  while(1)
  {
    if (Counter>=3000)
      lcd_puts("Seite 1");
    else
      lcd_puts("Seite 2");
  };

Gruß,
Magnetus

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...oder so...
  while(1)
  {
    while(Counter>3000);  // gib Seite 1 erst aus wenn Counter <= 3000
    lcd_puts("Seite 1");

    while(Counter<=3000);  // gib Seite 1 erst aus wenn Counter > 3000
    lcd_puts("Seite 2");
  };

Gruß,
Magnetus

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach nochwas

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

hat das was zu sagen?

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR(TIMER0_OVF_vect)       // alle 0.000256 Sekunden / 4 Mhz
  {
    Counter++;
    
    if( Counter == 6000 ) 
      {
        Counter = 0;
      }
  
  
  
  }
  
int main(void)
{  

    TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 );    /* Teiler auf CPU/1024 */
    TIMSK |= ( 1 << TOIE0 );          //
    sei();                    // Alle Interrupts aktiv
    
    lcd_init(LCD_DISP_ON);            /* Display initialisieren */
    
    
    
while(1)
  {
    while(Counter>3000);  // gib Seite 1 erst aus wenn Counter <= 3000
    lcd_puts("Seite 1");

    while(Counter<=3000);  // gib Seite 1 erst aus wenn Counter > 3000
    lcd_puts("Seite 2");
  };

 return 0;
}     

Hab das mal modifiziert

Er schreibt nur Seite 1

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Björn (Gast)
Datum:

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

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du den Code schon mal mit AVRStudio simuliert?

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ne bis jetzt noch nicht

Autor: Magnus Müller (Gast)
Datum:

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

Grund:

mit
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

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat sich erledigt ich hab den überlauf vergessen :)

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.