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
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?
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?
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.
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
intmain(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!