Hallo,
ich möchte gerne das Tutorial hier aus dem Forum über Drehencoder
Testen, allerdings mit einem ATmega328P 16MHz.
jetzt habe ich in der Funktion „encode_init“ die Timer Register
angepasst auf den 328p. Und möchte die Funktion encode_read2 nutzen.
ich benutze einen 2-bit encoder (bild)
aber irgenwie funktioniert das ganze nicht so recht, könnte mir hier
bitte jemand weiterhelfen??
Meine Vermutung ist das ich den Timer nicht richtig initialisiert habe,
aber ich komme nicht drauf.
[[https://www.mikrocontroller.net/articles/Drehgeber]]
so ist es aktuell drauf, keine Funktion +Bild
Thomas E. schrieb:> Michael H. schrieb:>> TCCR1B = (1<<WGM12) | (1<<CS11) | (1<<CS10); // CTC, prescaler 64>> OCR1A = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5); // 1ms>> TIMSK1 |= 1<<OCIE1A;>> }>>>> ISR( TIMER0_COMP_vect ) // 1ms for manual movement>> {>> Erstens heißt es COMPA und zweitens ist diese ISR dann für welchen> Timer?
Danke, das stimmt habe ich geändert das war noch nicht der Fehler.
ich möchte gerne das Tutorial hier aus dem Forum über Drehencoder
Testen, allerdings mit einem ATmega328P 16MHz.
jetzt habe ich in der Funktion „encode_init“ die Timer Register
angepasst auf den 328p. Und möchte die Funktion encode_read2 nutzen.
ich benutze einen 2-bit encoder (bild)
aber irgenwie funktioniert das ganze nicht so recht, könnte mir hier
bitte jemand weiterhelfen??
Meine Vermutung ist das ich den Timer nicht richtig initialisiert habe,
aber ich komme nicht drauf.
[[https://www.mikrocontroller.net/articles/Drehgeber]]
ich muß jetzt noch einmal nachfragen, ich komme mit der Rechnung so
nicht klar.
1
TCCR1B=(1<<WGM12)|(1<<CS12);// CTC, prescaler 256
2
OCR1A=(uint8_t)(XTAL/256.0*1e-3-0.5);// 1ms
3
TIMSK1|=1<<OCIE1A;
normalerweise Rechne ich den Vergleichswert. Taktfrequenz des
Controllers / den Vorteiler * der gewüschten Zeit -1.
Das wären ja 16000000/256 = 62500 * 0.001 (1ms) = 62,5 - 1 = 61,5
also Vergleichswert 65535- 61,5
wie kann ich das jetzt in dem Makro umsetzen, da habe ich ein Brett vorm
Kopf,
das müsste doch so stimmen ? dann müsste ja der ganze Code so
funktioniernen oder ?
Das passt schon.
Dein Timer läuft mit dem eingestellten Prescaler mit 62,5 KHz. Wenn du
bis 62,5 zählst, ist eine ms um.
Bis 62,5 kann der Timer aber nicht zählen, sondern bis 62 oder bis 63.
Die -0,5 dient zum Runden nach den bekannten Regeln.
OK, war mir total unsicher weil nichts leuchtet, jetzt frag ich mal
sicherheitshalber nocheinmal etwas zur Funktion und Verdrahtung.
also, wenn das ganze funktioniert wird der der Zählwert Binär an PORTC
ausgegeben. dh. je nach Wert müssten die LEDS von PC0-PC7 leuchten ?
ich habe an PORTC Die ANODE (+) und an GND eine gemeinsame Kathode
angeschlossen. // LEDs against VCC richtig
von dem Encoder habe ich den common pin an +5V gelegt. dh. beim
Zählimpuls gibt er Highpegel aus.
Michael H. schrieb:> von dem Encoder habe ich den common pin an +5V gelegt. dh. beim> Zählimpuls gibt er Highpegel aus
Bei Eingängen, ob für Taster oder Encoder, wird üblicherweise über einen
Pullup-Widerstand, meistens intern, Vcc angelegt und der Taster oder
Encoder schaltet gegen GND. Üblicherweise heißt: zu >99,9%. Das wird von
der Dannegger-Auswertung auch so erwartet.
So, wie du das machst, schaltet der Eingang zwischen Nichts und Vcc.
Aber "Nichts" ist nicht GND oder Null. Deswegen kann das auch nicht
funktionieren.
Peter D. schrieb:> Michael H. schrieb:>> Achso, dann sind die Spuren A und B LOW_AKTIVE>> Das ist egal
Richtig, nicht einmal die Zählrichtung sollte sich dadurch ändern.
> nur floaten dürfen sie nicht.
Das sollten Eingänge sowieso besser nie tun, benutzte auf jeden Fall
garnicht.
Also Danke für die Hilfe,
jetzt habe ich noch eine Frage und zwar ist am schluß eine Auswertung
mit diskreten Bauteilen.
und zwar habe ich mir das auch schon eimal gebaut. da kommt ja der
Zählimpuls ich sag jetzt mal 4-fach raus.
kennt sich jemand aus, wie man das auf zb. 8-fach mit Bauteilen
erweitern kann ?
Udo S. schrieb:> DDRD |= 0xf0; // PD0, PD1, INT0 PD2 und INT1 PD3 Eingänge
Kann man so schreiben, übersichtlicher fände ich:
1
DDRD|=(1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4);
Bei deiner Konfig geht auch 0xf0, der erfahrene Programmierer sieht da
das Hight-Nibble drin. Nur als kleiner Tipp ;).
Udo S. schrieb:> PORTD |= 0xff; // Pullup-activated, --- Activ LOW
Hiermit schaltest du nicht nur die Pullups ein, alle Ausgänge machst du
damit auch scharf. Ich würde nur da Pullups einschalten wo ich sie auch
definiert haben will.
Udo S. schrieb:> #define XTAL 11059200 // 11,059200MHZ
Setz hier noch ein UL hinter die 11059200, der Compiler kann (muss
nicht) auf dumme Ideen kommen, mit einem UL zwingt man ihn entsprechende
Berechnungen im Code später als unsigned long zu bewerten.
An deinem Code ansich sehe ich erstmal keinen Fehler, eigentlich sollte
das gehen wenn du am Encoder drehst. Aber 100 ist schon was, versuchs
doch erstmal mit 5 oder so ;)
Hallo sylaina,
Danke für Deine Antwort. Ich habe den val-Wert mal auf "==10"
eingestellt. PORT C zeigt den Wert 0b0000 1010 an, also 10 . Auch mein
LCD zeigt "10" an. Trotzdem wird PD7 nicht angesprochen. Die Ports sind
in Ordnung. Im Testprogramm werden alle LEDS aller Ports ordnungsgemäß
angesteuert.
Die Variable "val" ist doch integer, sodaß die if-Abfrage genau dieses
Register abfragt, oder ist da was falsch?
1
for(;;)
2
{
3
val+=encode_read1();// read a single step encoder
4
LEDS=val;
5
6
sprintf(Buffer,"Value = %6d",val);
7
lcd_setcursor(0,1);
8
lcd_string(Buffer);
9
10
// ####### Diese if-Abfrage möchte ich hier einsetzen, funktioniert aber nicht. ###########################
11
// PD7 soll toggeln, wenn die Achse des Motors eine bestimmte Anzahl von Umdrehungen durchgeführt hat
12
13
if(val==10)// Ist diese Abfrage von der Syntax falsch?
Der Vollständigkeit halber die komplette for-Schleife inclusiv Klammern
[c]
for(;;)
{
val += encode_read1(); // read a single step encoder
LEDS = val;
sprintf(Buffer, "Value = %6d", val);
lcd_setcursor(0,1);
lcd_string( Buffer );
// ####### Diese if-Abfrage möchte ich hier einsetzen, funktioniert aber
nicht. ###########################
// PD7 soll toggeln, wenn die Achse des Motors eine bestimmte Anzahl von
Umdrehungen durchgeführt hat
if(val==10) // vielleicht falsche Syntax?.
{
PORTD ^= ( 1 << PD7 );
}
}// Ende for
return 0;
}// Ende main
[/c)
Ja, jeder Übergang im Graycode erhöht den Wert "val" um einen Schritt.
Dieser "val-Wert" wird im LCD auch angezeigt. Die Lichtschranken werden
durch eine Encoderscheibe geschaltet. Also beide Impulse um 90 Grad
versetzt.
Die Anzeige im LCD und am PORT C zeigt genau das an, was die
Encoderscheibe an den 2 Lichtschranken bewirkt.
Vielleicht ist da irgendwo ein kapitaler Fehler, aber ich kann den nicht
erkennen.
Habe das LCD auch in anderen Programmen getestet. Die Anzeigen stimmen
mit den Werten in den Registern überein, also Addition, Subtraktion von
Variablen. Alles o.k.
Bloß dieser abgefragte "val-Wert" in der If-Schleife lässt PD7 nicht
toggeln.
PD7 ist OUTPUT. Habe ich in der void set(void) deklariert.
1
DDRD|=0xf0;// PD0, PD1, INT0 PD2 und INT1 PD3 Eingänge
2
PORTD|=0xff;// Pullup-activated, --- Activ LOW
... oder habe ich Dich falsch verstanden?
Ich checke das mal mit dem Scope. Vielleicht toggelt sie ja doch.Beim
Togglen sollte die LED zumindest glimmen. Sie bleibt aber dunkel.
Werde mal in der If-Schleife ein
Hallo,
ich habe die For-Schleife soweit minimiert und bitte um Hilfe von
jemandem, der sich einen Reim auf folgende Situation machen kann.
PD7 wird nicht gesetzt.....
Ich möchte anhand der Werte von "val" einen Motor steuern. Aber ich kann
den Wert von "val" nicht nutzen, um Positionen der Motorachse
abzufragen.
Der komplette Code von Peter Dannegger ist oben schon gepostet. Der Code
funktioniert, nur PD7 wird nicht gesetzt.
Puh, weißt du denn überhaupt, wie so ein Programm funktioniert?
Also nochmal, um den Ausgang zu aktivieren, muß der µC das folgende
Kommando ausführen und dazu sollte es möglichst irgendwo am Anfang des
Hauptprogramms stehen. Irgendwoanders "deklariert" hilft nicht.
DDRD |= 1<<PD7;
Hallo batman,
DAAAAAAAAAAAAAAAAAAAAAAAAAAAANK an Dich!!!!!! Ich weiß, wie Programme
funktionieren. Aber ich habe in der main vollkommen übersehen, daß ich
set(); nicht aufgerufen habe. Dadurch waren die PORTs natürlich nicht
deklariert. Das passiert, wenn man nicht so viel Routine hat.
Hatte den Kopf zu, wegen anderer Sachen. Du hast mir sehr geholfen.
Nochmals Danke!!!
Udo