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
for(;;){ Das ist eine Endlosschleife im Interrupt, sprich er geht einmal rein und nie wieder raus.
for(;;){ Du hast ja wohl nen Arsch offen eine Endlosschleife in einen Interrupt zu packen;)
holger schrieb: > Du hast ja wohl nen Arsch offen ts ts ts... Nehme Dir ein Beispiel an Floh so wird ein Schuh daraus
> Das ist eine Endlosschleife im Interrupt, sprich er geht einmal rein und > nie wieder raus. Die for-Anweisung ist in der main-Funktion.
Ich habs jetzt mal geändert. Meine Schleife ist doch nicht etwa in den Interupt gerutscht? Da war nur die Bemerkung verrutscht beim probieren.
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?
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!
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.
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?
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.
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?
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.
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; }
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)
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. :-)
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?
Habe ich gemacht, ist aber nicht so wichtig, der Wert wird ja nicht ausserhalb vom Int benötigt?
Ich krieg das mit dem Interrupt nicht hin. Ich denk ich werd ein extr Controller opfern für den Drehgeber
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
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.
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.
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.
HILFE, ich finde den Fehler nicht... Kann mir jemand helfen?
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.