Hallo ich bin absoluter Neuling beim Thema AVR Programmierung. Bei einem Fortbildunglehrgang den ich gerade besuche haben wir z. Zeit das Thema Mikrocontrollerprogrammierung und unser Dozent hat sich als einstieg in das Thema das Franzispaket mit dem ATTiny 13 rausgesucht. Die Grundlagen sind mir so weit auch so langsam geläufig nur ein sauberes entprellen der Tasten mit den hier im Forum vorgestellten Routinen will mir nicht so gelingen. Meine Schaltung hat 2 Taster an PB3 und 4 gegen Masse, eine LED an PB1 die im Takt des Timers blinkt und an PB2 ist eine Relaissteuerung angeschlossen. Die Codeschnipsel in dem Quelltext sind von Hannes Lux (Melodiegenerator mit Tiny 15) und eine abgeänderte Vorlage aus dem Franzis Baukasten. Ziel ist es mit einem Taster das Relais sauber zu schalten. Gruß Rico
1 | ldi A,5 ;Start mit Vorteiler / 1024 |
2 | out TCCR0B,A |
3 | ldi A,2 |
4 | out TIMSK0,A ;Timer Interrupt freigeben |
Schreib das nicht so! Benutze die Bitnamen!
1 | ldi A, (1<<CS02) | (1<<CS00) ;Start mit Vorteiler / 1024 |
2 | out TCCR0B,A |
3 | ldi A, (1<<TOIE0) |
4 | out TIMSK0,A ;Timer Interrupt freigeben |
Ich sehe in deinem Code nicht, wo du das einer Taste zugeordnete Bit wieder löscht, nachdem du den Tastendruck abgearbeitet hast. > nur ein sauberes entprellen > der Tasten mit den hier im Forum vorgestellten Routinen will mir > nicht so gelingen. Das bedeutet was genau? Gehört jetzt zwar nicht zum Problem, aber Code so einfach wie möglich schreiben! Gerade in Assembler
1 | taste1: |
2 | sbis pinb,2 |
3 | rjmp relais_an |
4 | sbic pinb,2 |
5 | rjmp relais_aus |
6 | relais_aus: |
Ein Bit kann entweder gesetzt oder gelöscht sein, aber nicht beides gleichzeitig. Wenn also relais_an nicht zutrifft, dann muss es relais_aus sein. Es gibt keine andere Möglichkeit. Daher muss man das auch nicht testen. Auch willst du hier eigentlich nicht das PIN Register abfragen, sondern das PORT Register. Denn du willst ja wissen, was du als letztes rausgeschrieben hast, welchen Zustand der Ausgang hat. PIN benutzt du, wenn es sich um einen echten Eingang handelt, also jemand von aussen am physikalischen Pin rumwerkelt (wie zb ein Taster)
1 | taste1: |
2 | sbis PORTB,2 |
3 | rjmp relais_an |
4 | relais_aus: |
Auch solche Dinge solltest du vermeiden
1 | rjmp ende_r |
2 | Ende_r: |
Das ist sinnlos und zieht den Code nur unnötig in die Länge. Die Grundidee einen gemeinsamen Rücksprungpunkt zu haben würde ich allerdings nicht unbedingt in Frage stellen auch wenn es in diesem konkreten Fall nicht notwendig ist. Man könnte das alles so schreiben
1 | taste1: |
2 | sbis PORTB,2 |
3 | rjmp relais_an |
4 | relais_aus: |
5 | cbi PORTB,2 |
6 | rjmp Schleife |
7 | relais_an: |
8 | sbi PORTB,2 |
9 | rjmp Schleife |
aber so, finde ich, ist das auch noch ok
1 | taste1: |
2 | sbis PORTB,2 |
3 | rjmp relais_an |
4 | relais_aus: |
5 | cbi PORTB,2 |
6 | rjmp ende_r |
7 | relais_an: |
8 | sbi PORTB,2 |
9 | Ende_r: |
10 | rjmp Schleife |
Gerade in Assembler ist der Grat zwischen "zu kompakt" und "gerade noch lesbar aber doch noch wartbar" sehr schmal. Aber grundsätzlich ist jede Anweisung eine potentielle Fehlerquelle und je weniger Anweisungen du hast, desto weniger Fehlerquellen gibt es (daher auch den überflüssigen Test entfernen. Der bringt nichts ausser der Gefahr die falsche Testbedingung oder den falschen Pin zu erwischen)
Rico schrieb:
> ich bin absoluter Neuling beim Thema AVR Programmierung.
Und warum dann in Assembler?
Karl heinz Buchegger schrieb u.A.: > Schreib das nicht so! > Benutze die Bitnamen! Es kommt immer auf die Situation an. Für "Schalter-Bits" nutze ich selbstverständlich die Bitnamen. Für Nummern-Bits (Zahl gibt die Zeile in einer Liste bzw. Tabelle an, hier die Liste der Vorteiler) bevorzuge ich allerdings die Zahl. > > Ich sehe in deinem Code nicht, wo du das einer Taste zugeordnete Bit > wieder löscht, nachdem du den Tastendruck abgearbeitet hast. Da wird der Hase im Pfeffer liegen... ;-) Joan P. (joan) schrieb: > Und warum dann in Assembler? Vermutlich deshalb, um den Tiny13 (und damit den AVR-Kern) verstehen zu lernen. Der kann nämlich kein C (und auch kein Bascom), der kann nur Maschinencode und der ist nunmal nur in ASM 1 zu 1 notierbar. Auch dem noch so coolen C++-Programmierer schadet etwas ASM-Wissen nicht, wenn er AVRs programmieren will. ...
Danke für die ersten Antworten. Ich habe den Quelltext jetzt den Hinweisen nach überarbeitet: Bitnamen statt Dezimalzahlen, unnötige Zeilen entfernt, und einen eigenen Zuordnungsfehler beseitigt. Leider funktioniert das Programm in Sachen Tastenabfrage immer noch nicht. Es tut sich nichts außer der blinkenden LED. Da die Tasten ja Low-Active arbeiten weiß ich auch nicht so recht wie ich die Pins von PortB im Simulator im AVR Studio einstellen soll (alle Pins auf High bis auf jenes wo eine Taste drückt sein soll oder einfach alles auf Low lassen). Danke für weiter Hinweise Gruß Rico
Rico schrieb: > Zeilen entfernt, und einen eigenen Zuordnungsfehler beseitigt. Leider > funktioniert das Programm in Sachen Tastenabfrage immer noch nicht. Es > tut sich nichts außer der blinkenden LED. :-) Du schaltest auf Ausgang: PB0 und PB1 wenn du das Relais umschalten willst, änderst du den Pin: PB2 PB2 ist aber gar nicht auf Ausgang gestellt Mach dir doch auch für das Relais und die LED ein .equ genauso wie du es für die Taster auch gemacht hast, dann passiert dir das nicht. (Übrigens: man muss das nicht t1 nennen, taster1 würde auch gehen, dann kann man plötzlich zb sbrc TastenFlags, Taster1 ;Taste 1 bet�tigt gewesen? - nein... im Source Code lesen :-) Die Initialisierung würde dann zb so aussehen ldi A, (1<<Led ) | (1<<Relais) out DDRB,A und das ein bzw. Ausschalten des Relais sbi PORTB, Relais bzw. cbi PORTB, Relais und das hat dann doch gleich eine ganz andere dokumentarische Qualität als cbi portb,0 (vor allen Dingen, weil an Portpin 0 eigentlich ja gar nichts angeschlossen ist :-) 2 Fliegen mit einer Klappe: Ein Fehler weniger und verstehen kann man auch leichter was der Sinn der Sache ist Und das beste vom ganzen: Wenn das Relais mal vom Pin 2 auf Pin 0 umziehen muss, brauchst du nur an einer Stelle (beim .equ) ändern und alles andere passt sich von alleine an. > Da die Tasten ja Low-Active arbeiten weiß ich auch nicht so recht wie > ich die Pins von PortB im Simulator im AVR Studio einstellen soll (alle > Pins auf High bis auf jenes wo eine Taste drückt sein soll ganz genau so. Denn so ist das ja auch in der Realität
Es spielt!!! Danke für diese Hilfe mit den letzte Korrekturen im equ Bereich stimmen jetzt alle Portbeziehungen. Das wichtigste was ich bislang noch nicht gewusst habe, sich aber jetzt geklärt hat ist das der Timer Interrupt 4 mal durchlaufen werden muss bis das ganze als Tastendruck gewertet wird und bei dem langsamen Takt mit dem der Tiny aus dem Franzis-Projekt läuft und den 1024 Teiler dauert es ca. 2 sek bis ein Tastendruck ausgewertet wird. Ich hab jetzt den Teiler auf 64 reduziert und jetzt geht alles in Echtzeit. Problem gelöst. Der Quelltext in diesem Beitrag enthält die funktionierende Fassung, falls mal ein anderer vor einem ähnlichen Problem steht. Dank und Gruß Rico
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.