Datum:
Hallo Ich bin ein totaler Anfänger aber ich habe schon hin und wieder mal ein kleines Programm in Assembler geschrieben. Ich habe jetzt eine kleine Relaisschalteinheit gebaut, ganz primitiv mit einem ATmega 16, einem LCD, zwei Tasten und 7 Relais. Das LCD zeigt an den Schaltzustand an. Die kleine Software lässt sich über eine Taste steuern. Taste drücken "Schalter 1" noch mal Taste drücken "Schalter 2" usw. Die Taster hängen an int0 und int1. Nun möchte ich aber hin und her schalten können ( vor und zurück ) und bekomme das nicht gebacken. :-( Hat jemand einen kleinen Codeschnippzel für mich oder kann mir erklären wie man ein kleines up/down Menü mittels Interuptsteuerung in Assembler hin bekommt ? Komme einfach nicht mehr weiter. Danke schon mal im vorraus.
Datum:
Hi Also, Taster an Interrupt halte ich nix von. Mach doch folgendes, was sich schon tausendfach bewährt hat. Nimm das EVA Prinzip. Einlesen, Verarbeiten und ausgeben. Dazu schreibst du dir erst einmal eine Routine, die die Eingänge in der Programmschleife einlesen und entprellen. Dazu gibt es genügend beispiele und ich hab da auch schon einiges dazu geschrieben. Anschließend bildest du dir eine Flanke, die du im Pogramm verarbeitest. Flankenbit gesetzt, dann Aktion und Bit zurücksetzen. Nnun muss erst wieder der Taster erneut betätigt werden, um ein Flankenbit zu setzen. Mit dieser Flanke kannst du nun zählen oder auch andere Aktionen durchführeen, aber vermutlich wirst du wohl mit einem Wert verschiedene Programmbereiche bearbeiten wollen. Flanke zu erzeugen ist einfach. Eingänge lesen Exclusiv - Oder mit den zuletzt gelesenen Eigängen Wenn nicht "0" dann Flankenbit durch Und- mit altem Zustand ist fallende Flanke Und mit neuem Zustand ist steigende Flanke Anschließend neue Eingänge ablegen
RCALL Read_IO ; Eingänge lesen Read_IO: IN R15, Portx STS New_In, R15 Push R15 LDS R16, Old_In EOR R15, R16 Push R15 ; Ergebnis von R15 merken And R15, R16 ; fallende Flanke, in R16 ist der alte Wert STS In_To_Low, R15 POP R15 ; Ergebnis von Exclusiv Oder zurückholen POP R16 ; neuen Eingangsstatus nach R!6 And R15, R16 ; steigende Flanke, in R16 ist der neue Wert STS In_To_Hig, R15 STS Old_In, R16 ret |
Bei der Bearbeitung prüfst du, ob ein bit in den Variablen für die Flanken gesetzt ist und setzt es nach Bearbeitung zurück. Hier geh ich davon aus, du hast die Taster an VCC Sind sie nach GND geschaltet, drehst du R15 gleich nach dem Einlesen vom Port mit COM-Befehl um. Die Entprellung ist hier noch nicht beerücksichtigt. Gruß oldmax
Datum:
Taster über externen interrupt kommt nicht gut, such hier einfach mal nach einem Artikel namens entprellung. Für das Menü könnte ich dir Menü Nummern empfehlen, in Verbindung mit dem Befehl ijmp, sozusagen das durch ein flagbit welches angibt, das irgendeine taste gedrückt wurde, ein unterprogramm aufgerufen wird, welches zuerst den Befehl ijmp verarbeitet. An dem jeweiligen label kannst du dann auswerten, welche taste genau gedrückt wurde und. kannst dann entsprechend drauf reagieren. Bei deinem vorhaben ist die methode zwar nicht die kürzeste, aber irgendwann willst du sicher mal größere Menüs bauen, mit mehr tasten, da lohnt sich das dann. Beispiele für den ijmp Befehl findest du hier im tutorial bei den vergleichen. Mfg Dennis
Datum:
Andreas K. schrieb: > wie man ein kleines up/down Menü mittels Interuptsteuerung in Assembler > hin bekommt ? Interrupt für Tasten ist die schlechteste Lösung... Bei dem Betreff > _Menüsteuerung mit zwei Tasten (Up/Down) in Assembler_ habe ich ein Verständnisproblem. Denn mit nur 2 Tasten stelle ich mir die Bedienung eines Menüs recht ätzend vor. Schreib' mal, wie Du Dir die Zuordnungen der Aktionen zu den Tastendrücken vorstellst, dann kann man Dir vielleicht konkret helfen. Bei der schwammigen Formulierung "Menü mit 2 Tasten" finde ich keinen Anfang. Durch Menüs am LCD navigiere ich gern mit 4 Tasten oder einem Dehgeber mit Taster. ...
Datum:
steht doch da, eine Taste vor Relais +1, die zweite Taste zurück Relais -1 ...
Datum:
Denis G: schrieb: > steht doch da, eine Taste vor Relais +1, die zweite Taste zurück Relais > -1 ... Richtig, das ist die Auswahl, welches Relais gemeint ist. Nun fehlt noch die Bedienung des ausgewählten Relais. ...
Datum:
Denis G: schrieb: > steht doch da, eine Taste vor Relais +1, die zweite Taste zurück Relais > -1 ... und die dritte Taste: Relais betätigen Oder alternativ, wenn man nur 2 Tasten hat: erste Taste: Relais + 1, wenn 7 -> dann 0 zweite Taste: angewähltes Relais betätigen Bei 7 Relais ist das noch akzeptabel. Dreh und Angelpunkt des Ganzen ist aber, dass man ein Register dafür abstellt, das es die Nummer des 'aktiven' Relais hält. Und auch ja: Tasten über Interrups sind eine schlechte Idee
Datum:
Karl Heinz Buchegger schrieb: > erste Taste: Relais + 1, wenn 7 -> dann 0 > zweite Taste: angewähltes Relais betätigen Richtig, dazu muss man aber den momentanen Zustand der Relais kennen. Mir wäre es aber lieber, wenn man das Ding blind bedienen könnte, also separate Tasten für Ein/Aus hätte. Denkbar und realisierbar wäre natürlich das Durchzappen mit kurzen Tastendrücken und das Schalten mit langen Tastendrücken. Aber ehe ich hier weiter herumspekuliere, sollte Andreas erstmal zu den bisherigen Antworten Stellung nehmen und die Aufgabestellung präzisieren. ...
Datum:
Ja, die Spekulationen zeigen sehr schön, daß die Aufgabenstellung völlig unausgegoren ist. Was man sich nichtmal im Kopf überlegt hat, kann man natürlich auch nicht programmieren. Überleg Dir also erstmal in Ruhe, was Du eigentlich willst. Und dann schreib es in Worten hin, sodaß jeder es auch verstehen kann. Peter
Datum:
Angehängte Dateien:Hallo Hannes.
Erst einmal vielen dank an alle die hier posten,. Mit soviel Resonanz
hatte ich gar nicht gerechnet.
Also mal kurz zu menem "Wunderkasten" Es handelt sich um ein
Antennenschalter
für Sende- und Empfangsbetrieb inkl. einem 50 W Dummyload. Der
Hardwareaufbau gestallte sich sehr aufwendig da 100w HF nicht den
Prozessor "zu nahe kommen durften". Diese Hürde habe ich gemeistert und
die HF macht auf dem Prossesor keinen Eindruck.
Sicherlich kann man so'n Ding viel einfacher bauen, aber das war ja
nicht meine Antrieb. Mir ging es hauptsächlich darum die Software dafür
zu schreiben. (learning by doing).
Zu meiner Menüvorstellung: 1. Vorwärts und rückwärts schalten (Up/Down)
2. In einer weiteren Entwicklungsphase
stelle ich mir vor ,in einem Untermenü,
die Eingänge zu Konfigurieren.Per längerem
Tastendruck in's Setup...... später.
Gut für mich, ist schon mal die Erkenntnis, das die Tastenabfrage per
interupt nicht der bessere Weg zu seien scheint.
Datum:
Hi, ...es ist definitiv der falsche Weg. Interrups sind dazu da um binnen kürzester Zeit (ns Bereich) auf Signale zu reagieren... Bei einem Taster leigst du im 10ms Bereich. Das macht man indem man pollt und ggf eine kleine Entprellung schreibt. Pin checken, zählen, wieder checken, wenn gleicher Zustand nach x checks, dann ist das Signal stabil und man nimmt den Taster als gedrückt an, wenn nicht, Zähler =0 und wieder checken.... so grob jedenfalls... JJ
Datum:
Hi >Gut für mich, ist schon mal die Erkenntnis, das die Tastenabfrage per >interupt nicht der bessere Weg zu seien scheint. Dann sieh dir das mal an: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten MfG Spess
Datum:
Ja, diesem Artikel habe ich mir schon zum zigtem mal reingezogen aber irgend wie mach das kein Licht bei mir an. Warscheinlich sehe ich den Wald vor lauter Bäumen nicht.
Datum:
angucken hilft auch nichts - lesen und verstehen schon eher... ...so eine Taste flattert halt unter Umständen wenn man sie drückt, das ist doch auch ganz logisch bei einem mechanischem Kontakt, der "zittert" halt... Nun sieht du zu dass du deine Pinabfrage im Controller so gestaltest dass du etwa 5-10 mal schneller abfragst als so ein typischer Preller eben dauert...so hast du die möglichkeit mitzuzählen... Man fragt also den pin ab, wenn er high (high sei mal bei gedrücker Taste)wird und das über x Runden bleibt ist der Tastzustand stabil, wenn er zwichendurch wieder low wird, zählt man wieder bei 0 los wenn er wieder high wird. Erst wenn x erreicht ist, ist klar, der Zustand ist stabil und man kann etwas machen... Daran gibts nichts nicht zu verstehen... JJ
Datum:
Hi
>Daran gibts nichts nicht zu verstehen...
Doch... gerade das ist es immer wieder, was hier nicht verstanden wird,
sonst käme niemand auf die Idee, einen Taster per ISR abzufragen. Oder
die Frage stellt, warum ein Zähler von Tastendrücken "Zufallszahlen"
generiert.
Kontaktprellen muss man verstehen, dann weiß man auch, wie man damit
umgehen muss.
Gruß oldmax
Datum:
Jens schrieb: > Man fragt also den pin ab, wenn er high (high sei mal bei gedrücker > Taste)wird und das über x Runden bleibt ist der Tastzustand stabil, wenn > er zwichendurch wieder low wird, zählt man wieder bei 0 los wenn er > wieder high wird. Erst wenn x erreicht ist, ist klar, der Zustand ist > stabil und man kann etwas machen... Komische Erklärung... wahrscheinlich versteht das nur ein insider... 1. Die meisten Tasten liegen doch auf Masse, also Low 2. Bedeutung X Runden 3. Wer zählt 4. Bedeutung X erreicht Könntest Du auf meine Punkte näher eingehen? Vielleicht ein Flußdiagramm dazu? Ich würde es gerne verstehen. Ich bin noch zu jung um zu sterben. :-)))
Datum:
Hi oldmax,
>>Kontaktprellen muss man verstehen...
du meinst wohl eher wie man dieses Problem löst.
Die Frage kommt nicht auf weil das Kontaktprellen nicht verstanden wird
sondern weil es meistens eines der ersten Dinge ist über die man
stolpert wenn man gerade am Anfang steht. Dahinter steckt die
Anforderung der Umsetzung des erkannten Problems in eine Softwarelösung
- das hat mit verstehen aber meiner Meinung nach weniger zu tun...
JJ
Datum:
Andreas K. schrieb: > Zu meiner Menüvorstellung: 1. Vorwärts und rückwärts schalten (Up/Down) OK. Ich hab mir dein Ausgansgposting noch mal durchgelesen. Es scheint so zu sein, dass du etwas machen willst, was man zb in der Windowsprogrammierung einen 'Radio Button' nennt. Das heißt bei dir: Von 7 Ausgängen ist nur einer aktiv. Mit den Tasten schaltest du den aktiven Ausgang um 1 weiter bzw. zurück. Ist also zu einem beliebigen Zeitpunkt der Ausgang 2 aktiv, dann bewirkt * ein Tastendruck 'Up': Ausgang 2 wird abgeschaltet. Ausgang 3 wird eingeschaltet * ein Tastendruck 'Down': Ausgang 2 wird abgeschaltet Ausgang 1 wird eingeschaltet Ist es das, was du dir unter 'Menüsteuerung' vorstellst? Da führt dann in der Tat kein Weg an einer sauberen Entprellung vorbei. Links wurden dir ja schon genannt. Und ich würde nach wie vor empfehlen in einem Register die Nummer des 'aktiven Ausgangs' zu halten. Diese Nummer wird entsprechend bei Tastendruck verändert und die Auswerteroutine schaltet dann die entsprechenden Relais ein/aus.
Datum:
Hallo "- -", das erklärt sich mit dem Tutorial und dem Bild: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten http://www.mikrocontroller.net/wikifiles/2/26/Entprellen.png Ok ?
Datum:
1. Die meisten Tasten liegen doch auf Masse, also Low die meisten tasten sind eckig oder rund - sie liegen auf der Platine. Sie sind im Grundzustand geöffnet, unterbrechen also den Stromkreis. 2. Bedeutung X Runden Ist das eine Frage? 3. Wer zählt ein in Software definierter Zähler? Oder wolltest du dich mit einer Stoppuhr daneben stellen? 4. Bedeutung X erreicht steht oben. >>Vielleicht ein Flußdiagramm dazu? Poste mal einen Ansatz deines Flussdiagrammes! >>Könntest Du auf meine Punkte näher eingehen? Jemanden der keinen Namen hat, antworte ich eigentlich garnicht... JJ
Datum:
Uwe S. schrieb: > Ok ? Nein, die Bilder und den Artikel dazu habe ich schon mehrfach gelesen. Jens hat mir einen Anstoß gegeben. Nur die Punkte die ich aufgezählt habe sind mir nicht ganz klar. Es muß doch dafür ein Schema geben wonach ich mich richten kann.
Datum:
Jens schrieb: > 1. Die meisten Tasten liegen doch auf Masse, also Low > die meisten tasten sind eckig oder rund - sie liegen auf der Platine. > Sie sind im Grundzustand geöffnet, unterbrechen also den Stromkreis. > 2. Bedeutung X Runden > Ist das eine Frage? > 3. Wer zählt > ein in Software definierter Zähler? Oder wolltest du dich mit einer > Stoppuhr daneben stellen? > 4. Bedeutung X erreicht > steht oben. >>>Vielleicht ein Flußdiagramm dazu? > Poste mal einen Ansatz deines Flussdiagrammes! >>>Könntest Du auf meine Punkte näher eingehen? > Jemanden der keinen Namen hat, antworte ich eigentlich garnicht... Also doch nur für insider?
Datum:
...nein. als erstes bitte mal eine vollständige Frage stellen. Wo hakt es denn mit dem Verständnis? Oder ist es vielleicht so, das die Vorkenntnis wie ein Controller arbeitet nicht vorhanden ist? Wir alle hier können nicht erahnen was du nicht verstehst, dazu muss man erstmal verstehen was nicht verstanden wird... Diese Erkenntnis ist die Basis um hier im Forum eine vernünftige Antwort zu bekommen :-) JJ
Datum:
-_- schrieb: > Uwe S. schrieb: >> Ok ? > > Nein, > die Bilder und den Artikel dazu habe ich schon mehrfach gelesen. > Jens hat mir einen Anstoß gegeben. Nur die Punkte die ich aufgezählt > habe sind mir nicht ganz klar. Was daran ist unklar? Taster werden sinnvollerweise so eingebaut, dass beim Drücken der Taster geschlossen wird und so der Taster eine Verbindung nach Masse herstellt. Um das Prellen auszuschalten benutzt man die Information * Taster prellen nicht ewig. Irgendwann hat sich die Feder im Taster beruhigt und bleibt dann im Zustand 'geschlossen'. * Was wird man daher tun? Man wird mit dem Auftreten des ersten Kontaktes diesen nicht sofort als 'Taster geschlossen' werten, sondern einfach mal eine gewisse Zeit abwarten und nachsehen, was da so am Eingang passiert. Ändert sich der Pegel in diesem Zeitraum wieder, dann prellt die Taste immer noch. Findet man den Eingang aber eine gewisse Zeit lang in immer demselben Zustand vor (und ist diese Zeit größer als das vermutete Prellen), dann kann man davon ausgehen, dass sich alles beruhigt hat und die Taste jetzt (für die nächste Zeit) dauerhaft als geschlossen zu betrachten ist. Denn: Kein Mensch kann eine Taste so schnell drücken und wieder loslassen, dass man das mit Prellen verwechselt. Prellen findet im Millisekunden bereich statt, Drücken und Loslassen dauert aber meistens mit Sicherheit länger als 1/10 Sekunde. Und das ist eine völlig andere Zeitdimension.
Datum:
Hallo - Namen kennen wir jetzt nicht -. Ich hatte mich in den Anfängen auch mit Entpressen beschäftigt und dann auf die Erklärungen in den beiden Thread zurückgegriffen: Beitrag "Tasten entprellen - Bulletproof" Beitrag "Entprellen für Anfänger" Nun verwende ich die Routinen von Peter Dannegger in einer angepassten Version in "C" und denke über das 'Problemchen' nicht mehr nach. Nur noch das Modul einbinden, die Tasten und den Port definieren, den Timer auf das Debounce-Intervall einstellen und los geht es. Ich verwende meistens einen Timer (0) mit 1ms und das Debounce-Intervall von 10ms. Je nach Anwendung aktiviere ich dann noch Defines um die Repeat (get_key_short() + get_key_long()) oder die Release Funktionen (get_key_release()) frei zu schalten. Vielleicht hilft dir das auch weiter. Ok ?
Datum:
Andreas K. schrieb: > Zu meiner Menüvorstellung: 1. Vorwärts und rückwärts schalten (Up/Down) Ich vermute mal, Du meinst damit einen Umschalter, d.h. es ist immer nur ein Relais gezogen. Dann müßte man noch wissen, erfolgt die Umschaltung unterbrechend oder überbrückend. Oder soll die Umschaltung ohne Last erfolgen? D.h. die HF wird ausgeschaltet, das alte Relais abgeschaltet, das neue zugeschaltet und dann wieder die HF ein. Und bei jedem Schritt einige 100ms warten. Das wird dann eine Statemaschine. Peter
Datum:
Hallo Karl Heinz Dein Ansatz sieht viel verspechend aus. Ich werde das mal daran probieren.. An Peter Der Amateurfunk ist keine zeitkritische Anwendung :-) Geschaltet wird nur lastfrei ( 1000 Euro Hardware werden es danken !) und wenn es ein,zwei oder drei sekunden dauert ist das durchaus ok. An sonsten glaube ich dass das jetzt hier vollkommen abschweift. Es geht nur um ein programmtechnisches hin und herschalten ! Relais 1 an, Relais 1 aus, Relais 2 an ..... usw.
Datum:
Hallo Andreas, kannst Du in "C" programmieren ? Dann könnte auch dieser Scheduler [1] und die tolle Idee dahinter, die richtige zeitliche Abfolge von Programmfolgen sehr erleichtern. Man(n) muss aber erst mal hinter die Idee des Beispielcodes kommen. Sehr zu empfehlen ! Link: [1] Beitrag "Wartezeiten effektiv (Scheduler)"
Datum:
Andreas K. schrieb: > An sonsten glaube ich dass das jetzt hier vollkommen abschweift. Es geht > nur um ein programmtechnisches hin und herschalten ! Wie Du meinst. Ich wollte nur drauf hinweisen, was Dein Programm alles beachten muß. Wir haben ähnliche Anwendungen, Hochspannung (bis 30kV) muß lastfrei umgeschaltet werden, sonst kleben die Relais. Der MC überwacht alle Netzteile, daß ja nicht ein Relais unter Spannung schaltet. Er macht also eine komplexe Ablaufsteuerung, die auch Wartezeiten beinhaltet, bis die Netzteile vollständig entladen sind. Dann schaltet er um und fährt die Netzteile wieder langsam hoch. Peter
Datum:
Hi Ich will da noch mal mit einsteigen. Macht es ihm doch nicht so schwer und lasst ihn das ruhig in Assembler machen. Ist doch gar nix dabei. Also, deine Tasten schalten nach GND. Ist ja auch praktisch, da kannst du die internen Pull-Up Widerstände des Controllers nutzen. Wie weit bist du mit deinem programm. Timer und IO-Parametrierung klar? Ich zeig dir mal, wie ich das löse. Meine Programmschleife besteht aus Loop: gefolgt von Read_IO mit Chk_IO teste ich die Ereignisse und mit Write_IO setze ich die Ausgänge. kurz
Loop:
RCALL Read_IO
RCALL IO_Debounce
RCALL Chk_IO
RCALL Write_IO
RJMP Loop
|
Die Initialisierung hab ich mal weggelassen, aber ich setze vorraus, das deine Timer_ISR im ms-Takt aufgerufen wird. Die Read_IO hab ich ja schon einmal beschrieben, aber jetzt mal mit einer "Entprellung".
;------Lesen aller Eingänge und Signalanpassung ---_-- ;***************************************************** ;* Port D 2-7 Eingänge (Taster) * ;* Port D 0 Bit 0 + 1 serielle Verbindung * ;***************************************************** Read_IO: ; Eingänge einlesen In R16, PInD ; Port B lesen COM R16 ; Bits drehen ANDI R16, 0b11111100 ; Bits 0 und 1 ausblenden STS New_In, R16 End_Read_IO: RET ;********************************************************* ;----------------- Eingänge entprellen ------------------- ;********************************************************* ;* für 6 Eingänge werden bei Wechsel der Pegel separate * ;* Prellzeiten gestartet. Nach Ablauf der Prellzeit ist * ;* in Work_Reg das gültige Eingangsbit gesetzt. * ;********************************************************* IO_Debounce: ; Prellzeit LDS R16, In_Debounce ; Eingänge unter Kontrolle LDS R17, New_In MOV Ablage_A, R17 EOR R16, R17 BREQ Deb_Time ; keine Änderung mehr ;-------------------------- prellt noch -------------------------------- STS In_Debounce, R17 LDI R17, 5 ; für 50 mSekunden Prellzeit STS Deb_Time, R17 RJMP End_Dbnc ;------------------------ Ablauf Prellzeit ------------------------------ Deb_Time: ; Prellzeit abwarten LDS R16, Deb_Time CPI R16, 0 BREQ End_Dbnc ; keine Prellzeit gesetzt ;-------------------- Millisekunden Flag auswerten --------------------- LDS R18, Time_Flag ANDI R18, 0b00000001 ; mSek Flag aus Timer bearbeiten BREQ End_Dbnc ;------------------------------ Flag bearbeiten ------------------------- LDS R18, Time_Flag ANDI R18, 0b11111110 ; 10 mSekunden STS Time_Flag, R18 ; und quittieren Dec R16 STS Deb_Time, R16 CPI R16, 0 ; Prellzeit 50 mSekunden abgelaufen ? BRNE End_Dbnc ;--------------- Flankenmerker 0->1 setzen ------------------ MOV R17, Ablage_A LDS R16, Old_In ; Eingang ist stabil MOV Ablage_B, R16 EOR R16, R17 ; steigende Flanke in Reg_A bilden MOV R17, Ablage_A ; letzten gültigen Status AND R17, R16 LDS R18, Event_To_1 OR R17, R18 STS Event_To_1, R17 ; neuen Eingang merken MOV R17, Ablage_B AND R17, R16 LDS R18, Event_To_0 OR R17, R18 STS Event_To_0, R17 MOV R17, Ablage_A ; Flankenmerker laden STS Old_In, R17 End_Dbnc: RET |
Nachn dieser Routine hast du die Eingänge von Port D 2- 7 in den Variablen "Event_To_1" und "Event_to_0" stehen, wenn das prellen vorbei ist. Sicher,von den Befehlen her geht's auch kompakter, aber ich denke, so ist es leichter nachvollziehbar. Alles, was du jetzt in Chk_IO machen musst, ist die Auswertung der Flankenbits. Du kannst beispielsweise mit dem Betätigen des Tasters ein Relais abschalten und beim loslassen eins vor oder zurückschalten und Relais wieder zuschalten. Als Ausgang definier ich mal Port B. Wenn du keinen externen Quarz dran hast (bezieht sich auf Atmega8), hast du ein volles Byte, also 8 Ausgänge. Auch hier verwendest du eine Variable für die Ausgangsbits als Zwischenpuffer. Da dein Programm nur auf die Flags reagiert, wird die Schleife ständig durchlaufen, das Ereignis aber nur einmal bearbeitet.
Chk_IO: LDS R16, In_To_1 Mov R1, R16 ANDI R16, 0b00001100 ; Taster 1 und 2 abfragen BREQ Chk_T1_off ; Wenn Ergebnis =0, dann weiter LDS R17, Schiebe_Var ; Variable mit Schieberegister für Hoch/runter COM R17 LDS R16, Ausgabe And R16, R17 ; löscht das aktuel gesetzte Bit in der Ausgabe STS Ausgabe, R16 Mov R16, R1 ANDI R16,0b11110011 STS In_To_1, R16 ; Flankenbit löschen RJMP End_Chk_IO ; Routine beenden Chk_T1_Off: LDS R16, In_To_0 Mov R1, R16 ANDI R16,0b00000100 ; jetzt nur Taster 1 abfragen BREQ Chk_T2_off ; Wenn Ergebnis =0, dann weiter mit Taster 2 LDS R17, Schiebe_Var ; Variable mit Schieberegister für Hoch/runter ROR R17 ; schiebe nach rechts BRNE Set_Bit_ok ; Wenn nicht 0 dann ablegen LDI R17, 0b10000000 ; Bit 7 setzen RJMP Set_Bit_Ok Chk_T2_Off: Mov R16, R1 ; noch mal abfallende Flanken laden ANDI R16,0b00001000 ; jetzt nur Taster 2abfragen BREQ End_Chk_IO ; Wenn Ergebnis =0, dann Ende LDS R17, Schiebe_Var ; Variable mit Schieberegister für Hoch/runter ROL R17 ; schiebe nach links BRNE Set_Bit_ok ; Wenn nicht 0 dann ablegen LDI R17, 0b00000001 ; Bit 0 setzen Set_Bit_Ok: STS Ausgabe, R17 ; Schiebevariable in Ausgabevariable schreiben Mov R16, R1 ANDI R16,0b11110011 ; Ereignisbits löschen STS In_To_0, R16 ; und zurückschreiben End_Chk_IO: RET |
Nun, es sollte klar sein, habe ich eine Taste gedrückt, ist un der Variablen "Ausgabe" kein Bit gesetzt. Ich hätte genausogut einfach eine 0 hinein schreiben können. Wenn aber nicht alle Bits benötigt werden, kann ja sein, sollte auch nur das Bit vom Schieberegister ausgeblendet werden. Ok, nun sind wir schon fast durch
Write_IO LDS R16, Ausgabe ;COM R16 ; Falls Relais auf "0"-Signal schalten... Out PortB RET |
Fehlt eigentlich nur noch die Timer-ISR. Die solltest du so einstellen, das du den Interrupt jede msek. ausführst. Dann einfach entsprechend reservierte Register hochzählen, so das du beliebige Zeiten erhälst. z.B. ich mach dir das mal mbis zur Sekunde, ohne jetzt die Register zu retten,
Timer_ISR: Push ..... LDS R17, Time_Flag LDI R16,10 Inc MSekunden CP MSekunden, R16 BRLO End_Timer ORI R17, 0b00000001 ; 10 Millisekunden CLR MSekunden Inc MSek_10 CP MSek_10, R16 BRLO End_Timer ORI R17, 0b00000010 ; 100 Millisekunden CLR MSek_10 Inc MSek_100 CPI MSek_100, R16 BRLO End_Timer ORI R17, 0b00000100 ; 1 Sekunde CLR MSek_100 Inc Sekunden LDI R16, 60 CPI Sekunden, R16 BRLO End_Timer CLR Sekunden ORI R17, 0b00001000 ; 1 Minute .... End_Timer: STS Time_Flag, R17 Pop ..... RETI |
Sollten Fehler drin sein, ich hab es nicht getestet, ist nur mal so schell runter geschmiert. Sollte dir aber bei deinem Problem helfen, den richtigen Ansatz zu finden. Gruß oldmax
Datum:
Aber Hallo :-) Das ist der Lösungsansatz den ich gesucht habe.!!! Danke Dir Oldmax. Es gibt sicherlich auch andere Wege, Aber den durchschaue ich :-) An alle C Programmierer: ... warum Assembler ? Na ja, ich finde Assembler einfacher als C und man kommt mit weniger Aufwand zum Ziel. Die Größe des Programmcodes spricht Bände. Auch die ewige Tipperei des Makefiles macht mich schlapp. Da ich absolut kein Windows benutze ist Assembler die erste Wahl für mich, Außerdem glaube ich nicht das es irgend etwas gibt das man nicht in Assembler programmieren kann. Meine Unwissenheit tut da nichts zur Sache.
Datum:
Andreas K. schrieb: > An alle C Programmierer: > ... warum Assembler ? Na ja, ich finde Assembler einfacher als C und man > kommt mit weniger Aufwand zum Ziel. Die Größe des Programmcodes spricht > Bände. Auch die ewige Tipperei des Makefiles macht mich schlapp. Da ich > absolut kein Windows benutze ist Assembler die erste Wahl für mich, > Außerdem glaube ich nicht das es irgend etwas gibt das man nicht in > Assembler programmieren kann. Meine Unwissenheit tut da nichts zur > Sache. Also das sind ja wohl alles Witzpunkte. Wenn du wenigstens vernünftige Argumente bringen würdest ;-) - Weniger Aufwand zum Ziel? Ich wette mit dir, dass du weniger Lines of Code in C hast, bei gleichem Programm - Größe des Programmcodes ist vor 10 Jahren die Waffe der Assemblerjünger gewesen. Außerdem kriegst du für nichtbenutzten Flash kein Geld zurück. - kein Windows? Sondern? Linux? Das ist doch mit GCC die C-Plattform schlecht hin - Makefiles schreibt man, wenn überhaupt ein mal. Oder man lässt sie sich automatisch generieren. Das kann sogar AVR-Studio. - Ich glaube nicht, dass es irgendwas nicht gibt, was man in C programmieren kann. Du hast nur keine Lust die Sprache zu lernen, was (für mich) Ok ist. Aber schiebe hier nicht so einen Unsinn vor.
Datum:
Na ganz so ist dem nicht :-) Ich habe mit C Angefangen und bin dann bei Assembler gelandent, und ja es gibt kein Geld zurück, und ja du hast recht Linux ist die Oberfläche für C. WinAVR ist nur Portiert. Trotzdem komme ich mit ASM besser zu recht. Es gibt für alles ein für und wieder. Am Ende muss das jeder für sich entscheiden. Einen schönen Abend wünsche ich Dir noch Simon.
Datum:
Andreas K. schrieb: > Am Ende muss das jeder für sich entscheiden. Wohl wahr! Jedem so wie er das will. > Einen schönen Abend wünsche ich Dir noch Simon. Dito
Datum:
Angehängte Dateien:Andreas K. schrieb: > Trotzdem komme ich mit ASM besser zu recht. Ich auch... Hier mal ein 4 Jahre altes Beispiel für so etwas Ähnliches (kein Antennenumschalter, sondern ein Antennen-Anpassgerät, dass verschiedene Spulen in die Zuleitung einschleift bzw. wieder herausnimmt. Statt LCD wird allerdings Siebensegmentanzeige benutzt. ...

