mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mikrocontroller hängt Interrupt schuld?


Autor: Micha (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe eine frage zur Programmierung meines AtMega8.
Ich arbeite mich gerade in ein C Projekt ein und habe ein Problem.

Ich habe den Code schon soweit wie möglich eingegrenzt, nun weiß ich 
aber nicht mehr weiter.

Ich habe einen Drehgeber angeschlossen und einen Codeschnippsel aus der 
Codesammlung benützt um diesen abzufragen.
Jetzt ist das Problem, egal welchen Code ich jetzt in die While- oder 
Main-Schleife schreibe, wird der Encoder nicht mehr weitergezählt. Egal 
ob feriger Entprellcode oder selbstgeschriebener.

Kann es sein das wenn ich eine Funktion aufrufe, das der µC nicht mehr 
aus der (Haupt) Schleife kommt? Ich dachte daführ ist der Interupt da, 
um regelmäsig oder bei Ereignissen aufgerufen zu werden?

Was mache ich falsch?

Ich habe mal den Code angehängt

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
for(;;){
Das ist eine Endlosschleife im Interrupt, sprich er geht einmal rein und 
nie wieder raus.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
for(;;){

Du hast ja wohl nen Arsch offen eine Endlosschleife
in einen Interrupt zu packen;)

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger schrieb:
> Du hast ja wohl nen Arsch offen

ts ts ts...

Nehme Dir ein Beispiel an Floh so wird ein Schuh daraus

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das ist eine Endlosschleife im Interrupt, sprich er geht einmal rein und
> nie wieder raus.

Die for-Anweisung ist in der main-Funktion.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin schrieb:
> Die for-Anweisung ist in der main-Funktion.

Such die nächste :-)

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Such die nächste :-)

Scroll & gefunden :)

Autor: Micha (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habs jetzt mal geändert.

Meine Schleife ist doch nicht etwa in den Interupt gerutscht? Da war nur 
die Bemerkung verrutscht beim probieren.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Micha schrieb:
> Ich habs jetzt mal geändert.

und funktionierts?
Apropos, deine Variable i wird ja nur im Interrupt verwendet, warum 
machst du sie global?

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verwende diese doch auch als Variable für die for-schleife.
Kann ich aber auch vor der schleife machen!?

Jup, Funktioniert. Ich muß nur gerade wieder allen Code zusammenbauen 
den ich zum Testen gelöscht hatte.

DANKE!

Autor: Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Micha schrieb:
> Ich muß nur gerade wieder allen Code zusammenbauen
>
> den ich zum Testen gelöscht hatte.

Das löscht man doch nicht! Niemals!

/*
Das kommentiert man aus!
*/

mfg.

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jup, Funktioniert!

Jetzt brauch ich nur noch eine Inspiration für ein Menü auf einem 
4x20LCD.
Ich dachte ich mach das über ein Array und rufe nur einen festen Text 
mit einem Zeiger auf.
Aber wie kann man einen Text mit einem Array verknüpfen?

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich hab's in einem Projekt so gelöst, die Variablen werden im 
PROGMEM gespeichert und sind so resourcenschonender:
const char variable0[]PROGMEM = "text1";
const char variable1[]PROGMEM = "text2";


PGM_P menu[xx]PROGMEM=
  {
  variable0,      //"text1"
  variable1               //"text2"
        };

  
strcpy_P(Puffer, (PGM_P) pgm_read_word(&menu[1]));
lcd_string(Puffer);


-> müsste an's LCD den String "text2" übergeben.

Autor: Micha (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Danke für die Hilfe mit dem Menü, aber ich hänge schon wieder vorher 
fest.
Das Menü hat schoneinmal funktioniert.
Dann habe ich aber gemerkt das ich alle Funktionen und Aufrufe in den 
Interupt geschrieben habe. Dadurch hat alles gesponnen.

Jetzt habe ich alles entwirrt und eine Main geschriebn mit while(1) die 
eigentlich als Dauerschleife laufen sollte und so bei jedem Durchlauf 
die Funktion encode_read2() aufrufen soll und damit zählt.

Doch irgendwie habe ich das gefühl das nach einem Durchlauf von While 
schluss ist. Es passiert nichts mehr!

Eigentlich sollte doch der Timer einen Interupt aufrufen und die Anzahl 
der Drehungen im enc_delta speichern.

Was passt nicht, ich suche seit Tagen daran??

Kann mir jemand weiterhelfen?

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, was ich vergessen habe:

wenn ich encoder_read() alleine in einer for(;;) Schleife dauernd 
aufrufe funktioniert zwar das Auslesen und Zuweisen, aber sonnst wird 
kein Code mehr ausgeführt.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In deiner Endlosschleife hast du nochmal eine Endlosschleife, daher 
kommt er nicht weiter:
    for(;;){
//  for(i = 0; i < 1; i++){
    inc += encode_read2();          // read a two step encoder
    LEDS = inc;
  }

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau, das ist ja das was mich verwirrt.
Wenn ich das so mache:



while(1)

  for(i = 0; i < 1; i++){
    inc += encode_read2();          // read a two step encoder
    LEDS = inc;
  }


//nächstes...


}


dann sollte er ja nir einmal durchlaufen, den inc mit dem neuen Wert 
aktualisieren und das nächste machen.

Nachdem er die While durch hat sollte er ja wieder von vorne anfangen, 
aber das macht er nicht. (denke ich zumindest)

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Micha schrieb:
> Nachdem er die While durch hat sollte er ja wieder von vorne anfangen,
> aber das macht er nicht. (denke ich zumindest)

In dem geposteten Programm ist aber eine for(;;) in der while-Schleife. 
Diese wird nie verlassen also kommt er auch nie wieder zum Anfang der 
while-Schleife.
Noch als Bitte:
Formatier deinen Code ordentlich.
viele Leerzeilen raus, ist einfach bescheuert die Schleife nicht in 
einem Blick (Anfang und Ende) zu sehen.
Außerdem einrücken, und zwar passend.
Und du musst dich entscheiden, ob die Klammer auf hinter der Bedingung 
oder in der neuen Zeile steht, aber niemals (!!) mischen.
:-)

Autor: Micha (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So, hab mal bisschen aufgeräumt.
Ich hab so viel probiert und gemacht, da ist natürlich unordentlich 
geworden.

Ich habe jetzt auch mal die for(;;) rausgelöscht, um damit anzudeuten 
das das nicht das Problem ist, sondern nur von mir zum Probieren das die 
Funktion auch gegeben ist von encode_read2().

Das Problem ist aber wenn ich das encode_read2() ganz normal mit den 
anderen Befehlen in der While.Schleife aufrufe, bekomme ich keine Werte 
mehr, die LEDS an PORTC zählen nicht mehr auf und ab (Das Menü im 
Display auch nicht mehr)???

Warum ruft die Funktion encode_read2() keine werte mehr ab?

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
last auch mal als volatile deklarieren?

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe ich gemacht, ist aber nicht so wichtig, der Wert wird ja nicht 
ausserhalb vom Int benötigt?

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktioniert aber leider auch nicht.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich krieg das mit dem Interrupt nicht hin.
Ich denk ich werd ein extr Controller opfern für den Drehgeber

Autor: Jazon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Micha kannst du mir bitte mal erleutern was du hier machst?

cli();
val = enc_delta;
enc_delta = val & 1;
sei();

was machen die Funktionen cli() und sei() und
val = enc_delta;
enc_delta = val & 1;
ist meiner meinung doppelt gemoppelt du könntest doch einfach
enc_delta=enc_dleta & 1;
machen würde auf das selbe raus kommen.

for(i = 0; i < 1; i++)
  {
    inc += encode_read2();          // read a two step encoder
    LEDS = inc;
  }

die for schleife macht hier auch keinen Sinn weil du nur einmal in die 
Schleife reingehst.

  for(i = 0; i < 1; i++)
    {
    if( debounce( PIND, PD6 ) )
      D_taster ^= 1<<PB1;   //toggle/schreibe PB1 in PORTC
    PORTB = D_taster;

    }
hier genau das selbe.

poste mal den quelcode für cli() und sei() vielleicht ist dort irgendwas 
faul.

Mfg

Jazon

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weis das ich da unnötige Schleifen habe. Die ied allerdings nur zum 
testen da.

Cli() und sei() sind die funktionen um Interupts zu deaktivieren und 
aktivieren.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den Code um enc_delta hab ich aus dem Drehgeberturtorial aus dem Forum.
Warum die das so machen kann ich gerade nicht sagen.

Wenn ich aber encode read nicht dauerhaft aufrufealso nur für sich 
selbst funktioniert der Drehgeber nicht mehr.

Eigentlich solte diese Funktion doch die anzahl der drehungen seit dem 
letzten aufruf ausgeben.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab heute noch mal paar Stunden probiert. Hat aber nicht gebracht. 
Was kann da noch sein, der code ist doch ok?
Das liegt bestimmt an dem Interupt. Vo diesen hab ich leider nicht viel 
Ahnung.

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HILFE,

ich finde den Fehler nicht...

Kann mir jemand helfen?

Autor: Frank Link (franklink)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
versuchs mal damit, dass Du Deinen Code richtig aufräumst!

Alle Initialisierungen gehören an den Anfang von Main und ausserhalb der 
Endlosschleife.

In Deinem Code rufst Du innerhalb der while Schleife immer wieder die 
Initialiserung der Inkrementalgeber-Routinen auf.

Grundlegender Aufbau sollte sein:
int main(void)
{
    // Variablen deklarieren
   
    // Initialisierungs Routinen aufrufen

    // Interrupt freigeben

   while( 1 )
   {
   {
}

Alles andere ist sinnfrei und macht keinen Spass zu lesen.

Gruß
Frank

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank Link schrieb:
> Hallo,
> versuchs mal damit, dass Du Deinen Code richtig aufräumst!

Volle Unterstützung.
Die Programmierer mit den seltsamsten Fehlern sind meistens auch 
diejenigen deren Code absolut unleserlich und ein einziges 
unübersichtliches Durcheinander ist.

Und weiter oben wurde es schon angedeutet: Übersicht erreicht man nicht 
dadurch, dass man ständig hunderttausend Leerzeilen einfügt. 1 Leerzeile 
zur Abgrenzung eines logischen Blocks reicht völlig.

Und deine ominösen Einmal-For-Schleifen. Spar sie dir einfach. Die 
bringen nichts ausser Verwirrung.

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Tip. Es funktioniert jetzt endlich. Warum ich das selber 
nicht gesehen habe ist ja fast klar. Ich hab den Code jetzt mal richtig 
aufgeraumt.
Den werd ich morgen auch mal einstellen.

Danke für eure hilfe!

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.