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


von Micha (Gast)


Angehängte Dateien:

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

von Floh (Gast)


Lesenswert?

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

von holger (Gast)


Lesenswert?

for(;;){

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

von Holger P. (Gast)


Lesenswert?

holger schrieb:
> Du hast ja wohl nen Arsch offen

ts ts ts...

Nehme Dir ein Beispiel an Floh so wird ein Schuh daraus

von Martin (Gast)


Lesenswert?

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

Die for-Anweisung ist in der main-Funktion.

von Floh (Gast)


Lesenswert?

Martin schrieb:
> Die for-Anweisung ist in der main-Funktion.

Such die nächste :-)

von Martin (Gast)


Lesenswert?

> Such die nächste :-)

Scroll & gefunden :)

von Micha (Gast)


Angehängte Dateien:

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.

von Floh (Gast)


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?

von Micha (Gast)


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!

von Thomas E. (thomase)


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.

von Micha (Gast)


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?

von Andreas (Gast)


Lesenswert?

Also ich hab's in einem Projekt so gelöst, die Variablen werden im 
PROGMEM gespeichert und sind so resourcenschonender:
1
const char variable0[]PROGMEM = "text1";
2
const char variable1[]PROGMEM = "text2";
3
4
5
PGM_P menu[xx]PROGMEM=
6
  {
7
  variable0,      //"text1"
8
  variable1               //"text2"
9
        };
10
11
  
12
strcpy_P(Puffer, (PGM_P) pgm_read_word(&menu[1]));
13
lcd_string(Puffer);

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

von Micha (Gast)


Angehängte Dateien:

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?

von Micha (Gast)


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.

von Floh (Gast)


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;
  }

von Micha (Gast)


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)

von Floh (Gast)


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.
:-)

von Micha (Gast)


Angehängte Dateien:

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?

von Floh (Gast)


Lesenswert?

last auch mal als volatile deklarieren?

von Micha (Gast)


Lesenswert?

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

von Michael (Gast)


Lesenswert?

Funktioniert aber leider auch nicht.

von Michael (Gast)


Lesenswert?

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

von Jazon (Gast)


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

von Michael (Gast)


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.

von Michael (Gast)


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.

von Michael (Gast)


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.

von Micha (Gast)


Lesenswert?

HILFE,

ich finde den Fehler nicht...

Kann mir jemand helfen?

von Frank L. (franklink)


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:
1
int main(void)
2
{
3
    // Variablen deklarieren
4
   
5
    // Initialisierungs Routinen aufrufen
6
7
    // Interrupt freigeben
8
9
   while( 1 )
10
   {
11
   {
12
}

Alles andere ist sinnfrei und macht keinen Spass zu lesen.

Gruß
Frank

von Karl H. (kbuchegg)


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.

von Micha (Gast)


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!

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.