Hallo zusammen Ich arbeite schon seit längerer Zeit an meinem Uhrenprojekt mit meinem ATmega8 und bis jetzt habe ich zwei Programme geschrieben. Einmal eine Uhr mit Wochentagsanzeige (und nicht funktionierendem Datum) und ein Programm mit einer Weltuhr (also vier verschiedene Städte in vier verschieden Zeitzonen). Nun möchte ich die zwei Programme in eins integrieren. Dafür wollte ich einen Taster verwenden, doch nach ein paar Versuchen, dachte ich, dass es nur mit einem externen Interrupt funktioniert. Ich möchte nämlich zwischen der Weltuhr und der normalen Uhr durchswitchen, am besten immer nach Tasterdruck. Brauche ich einen externen Int? Ist meine Idee realisierbar? P.S im Anhang findet ihr die zwei Programme (bei Anregungen gerne melden!)
ok, ja, ich weiß wie man Taster benutzt. Ich habe es schon mal probiert, jedoch habe ich es nicht geschafft aus der Tasterabfrageschleife herauszukommen... Hast du da einen Tip?
Joachim Jakob schrieb: > Brauche ich einen externen Int? Für die Umschaltung: nein > Ist meine Idee realisierbar? Ja, einfach in regelmäßigen Zeitabständen einen Taster abfragen, den entprellen und im Program ein Flag setzen. Dieses Flag wechselt bei einem Tastendruck zwischen 1 und 0. Je nach Flag springst du zu "datum" oder "weltuhr". Diese beiden (bisher eigenständigen) Programme springst du je nach Flag-Zustand an.
?!? schrieb: > Dieses Flag wechselt bei > einem Tastendruck zwischen 1 und 0. Je nach Flag springst du zu "datum" > oder "weltuhr". Diese beiden (bisher eigenständigen) Programme springst > du je nach Flag-Zustand an. Ja genau so wollte ich das machen! aber ich wusste nicht wie ich die Taster Abfrage machen soll, deswegen dachte ich an den externen Interrupt... Also wie soll ich die Abfrage machen?
Im Datenblatt ist unter 'I/O Ports' die gewünschte Information zu finden; es empfiehlt sich, das ganze Kapitel zu lesen, in Ihrem Fall ist aber nur PINx wichtig, sowie die dazugehörenden Befehle sbic bzw. sbis.
Joachim Jakob schrieb: > ?!? schrieb: >> Dieses Flag wechselt bei >> einem Tastendruck zwischen 1 und 0. Je nach Flag springst du zu "datum" >> oder "weltuhr". Diese beiden (bisher eigenständigen) Programme springst >> du je nach Flag-Zustand an. > > Ja genau so wollte ich das machen! > aber ich wusste nicht wie ich die Taster Abfrage machen soll, deswegen > dachte ich an den externen Interrupt... > Also wie soll ich die Abfrage machen? Einfach den µC-Pin, wo der Taster dran hängt, abfragen. Taster vom Pin gegen GND, internen Pullup aktivieren. Wenn der Taster gedrückt ist, liegt Low an, wenn er nicht gedrückt ist, liegt high an. Und dann arbeitest du am besten diesen Beitrag durch: http://www.mikrocontroller.net/articles/Entprellung oder suchst im Forum den Suchbegriff "entprellung" ein, da findest du sehr viele Beiträge.
Ein Einfachstbeispiel für ein schnelles Erfolgserlebnis am Sonntagabend: .equ PORT_Taster = PORTB .equ PIN_Taster = PINB .equ Taster = 5 ; gegen GND sbi PORT_Taster,Taster ; pullup einschalten im Modul 'Datum' einbauen: sbis PIN_Taster,Taster rjmp Weltuhr ; weiter mit Datum im Modul 'Weltuhr' einbauen: sbic PIN_Taster,Taster rjmp Datum ; weiter mit Weltuhr Und sobald Sie sich dann ärgern, dass Sie für die Weltuhr den Taster gedrückt halten müssen, befassen Sie sich mit der schon erwähnten Entprellung und machen die Sache richtig.
Also ich habe das jetzt wie oben genannt ausgeführt, aber wie befürchtet wird nichts angezeigt, da das Programm in der Tasterabfrageschleife hängen bleibt und deshalb der LCD nicht aktualisiert wird... Lösungen?
der alte Hanns schrieb: > sbi PORT_Taster,Taster ; pullup einschalten > > im Modul 'Datum' einbauen: > sbis PIN_Taster,Taster > rjmp Weltuhr > ; weiter mit Datum > > im Modul 'Weltuhr' einbauen: > sbic PIN_Taster,Taster > rjmp Datum > ; weiter mit Weltuhr kannst du mir das bitte genauer erläutern?
Ich wuerde mir an deiner Stelle ein 3. Programm schreiben. Knackpunkt an der ganzen Sache ist, dass beide Aufgabenstellungen ja im Grunde auf der gleichen Grundlage beruhen - prinzipiell hast du es mit einer Uhr zu tun. Und zwar nur mit EINER Uhr. Langer Rede kurzer Sinn: die Ausgabe muss aus dem Timer Interrupt raus. Im Timer Interrupt machst du nur die Weiterzaehlung der Register, die deine Uhrzeit bzw. das Datum darstellen. Nicht mehr! Die Ausgabe der Uhrzeit bzw. Datum, bzw. des Wochentags kommt in die Hauptschleife. Dort und nur dort wird aufs Display ausgegeben. Und bei Bedarf wird dann dort, zum Beispiel wenn eine Taste gedrueckt ist, auf eine andere Anzeige umgeschaltet, indem ganz einfach eine andere Ausgaberoutine angesprungen wird. Zum Beispiel eine, die zur Zeit noch ein paar Stunden dazu zaehlt oder weg zaehlt und dabei, wieder nur fuer sich lokal, dann auch das Datum und den Wochentag korrigiert. Aber der erste Schritt besteht darin, dass die innerste Uhr erst mal nur fuer sich zaehlt - ganz ohne Ausgabe. Dieser innerste Kern, der Timer Interrupt, ist nur dafuer zustaendig, die Zeit zu zaehlen und zu registrieren. Wie, wann, wo und auf welche Art die Zeit dann ausgegeben wird, soll nicht das Bier dieses inneren Uhrenkerns sein. Das regelt das Hauptprogramm in der Hauptschleife. Daher das 3. Programm, in dem du dir erst mal eine Uhr machst, die genau so funktioniert.
ich habe zwei posts weiter oben noch einen code gepostet, der meiner Meinung nach deinen Anforderungen entspricht. Ich verstehe auch was du meinst, aber meiner meinung nach ist das nur mit einem ext Interrupt zu realisieren, denn die Ausgabe muss doch jede Sekunde stattfinden, um die Sekunden zu aktualisieren und wenn das Programm immer mit dem Abfragen des Tasters beschäftigt ist, kann keine Aktualisierung stattfinden. So sehe ich das..
Joachim Jakob schrieb: > ich habe zwei posts weiter oben noch einen code gepostet, der meiner > Meinung nach deinen Anforderungen entspricht. Seh ich gleich mal rein > Ich verstehe auch was du meinst, aber meiner meinung nach ist das nur > mit einem ext Interrupt zu realisieren, nicht nur, keinesewgs > denn die Ausgabe muss doch jede > Sekunde stattfinden, um die Sekunden zu aktualisieren und wenn das > Programm immer mit dem Abfragen des Tasters beschäftigt ist, kann keine > Aktualisierung stattfinden. Der Interrupt kann zb in ein Register eine 1 reinschreiben, wenn 1 Sekunde gezaehlt wurde. Das Hauptprogramm geht nach dem Muster vor, dass es nicht nur den Taster abfragt, sondern auch dieses Register. Steht es auf 1, dann wird das Display auf den neuesten Stand gebracht und in dieses Register eine 0 hineingeschrieben. Diese 0 steht dann so lange im Register, bis sie vom Timer Interrupt wieder durch eine 1 ersetzt wird um anzuzeigen, dass 1 Sekunde vergangen ist, woraufhin in der Hauptschleife die Uhrenanzeige wieder auf den neuesten Stand gebracht wird. Lass die Idee mit Taster und externem Interrupt wieder fallen. Als reine Softwareloesung gibt das eine Menge Aerger.
Karl Heinz schrieb: > Das Hauptprogramm geht nach dem Muster vor, dass es nicht nur den Taster > abfragt, sondern auch dieses Register. Steht es auf 1, dann wird das > Display auf den neuesten Stand gebracht und in dieses Register eine 0 > hineingeschrieben. Diese 0 steht dann so lange im Register, bis sie vom > Timer Interrupt wieder durch eine 1 ersetzt wird um anzuzeigen, dass 1 > Sekunde vergangen ist, woraufhin in der Hauptschleife die Uhrenanzeige > wieder auf den neuesten Stand gebracht wird. Diese Vorgehensweise hatte ich bei den zwei einzelnen Modulen auch, jedoch muss ich bei dem Programm mit dem Taster immer zurück zur Tasterabfrage springen, weshalb ich dieses Aktualisierungsregister weggenommen habe... Karl Heinz schrieb: > Lass die Idee mit Taster und externem Interrupt wieder fallen. Als reine > Softwareloesung gibt das eine Menge Aerger. Hast du vielleicht eine andere Idee, wie ich die zwei Module verbinden kann?
Joachim Jakob schrieb: > Hast du vielleicht eine andere Idee, wie ich die zwei Module verbinden > kann? Das was du hast, sieht doch gar nicht so schlecht aus. Du musst das nur ein wenig anders organisieren. Das Hauptprogramm sieht im Prinzip so aus:
1 | .... |
2 | Initialisierung |
3 | Timer aufsetzen, etc. |
4 | ... |
5 | |
6 | sei |
7 | |
8 | main: |
9 | |
10 | Tasterabfrage, ist ein Taster gedrückt worden? |
11 | wenn ja, dann Modus von 1 auf 0 umstellen, bzw. umgekehrt |
12 | |
13 | |
14 | wenn Modus steht auf 0, dann normale |
15 | Uhrenanzeige |
16 | |
17 | wenn Modus steht auf 1, dann Weltuhranzeige |
18 | |
19 | rjmp main |
20 | |
21 | |
22 | normale Anzeige: |
23 | mache einen Durchlauf durch die normale Anzeige |
24 | aktuelle Uhrzeit auswerten und einmalig auf die Anzeige schreiben |
25 | |
26 | rjmp main |
27 | |
28 | |
29 | Weltuhranzeige: |
30 | mache einen Durchlauf durch die Weltuhranzeige |
31 | |
32 | rjmp main |
du bist noch zusehr davon behaftet, dass der jeweilige Anzeigemodus erst bei Tastendruck verlassen wird. Du kanst die Sache genau umgekehrt aufziehen. Jeder Anzeigemodus wird, nachdem er seine Anzeige gemacht hat, verlassen und kehrt wieder zu main zurück. Dort wird dann wieder die Tastenauswertung gemacht und je nach Modus gehts wieder zurück in den jewiligen Anzeigemodus, der die aktuelle Uhrzeit EINMALIG wieder auf die Anzeige klatscht. Ist er damit fertig, gehts wieder zurück zu main, Tastenauswertung und Entscheidung anhand des Modus, welche Anzeige zu machen ist.
Ganz wichtig: die lcd_clear solltest du dir (ausser vielleicht beim Moduswechsel) abschminken. Das flackert sonst wie Sau! Statt dessen willst du deine Anzeige in jedem Modus so organisieren, dass immer nur die jewieligen Stellen überschrieben werden. Also einfach über das, was bereits an der Anzeige steht drüber schreiben. Dann flackert da auch nichts.
AUch solltest du dir mal darüber Gedanken machen, dir eine Funktion zu schreiben, mit der du fixe Texte ausgeben kannst. Die jedesmal händisch in Einzelzeichen aufzudröseln und für jedes Zeichen selbst einzeln lcd_data aufzurufen, ist dann schon sehr mühsam. Das kann Programmcode genausogut für dich erledigen. Hier zb ist eine für die UART geschrieben worden: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Speicher#Flash-ROM_2 (Scroll ein wenig runter bis zu "Fallbeispiel Zeichenketten" Das lässt sich leicht auf die Verwendung von lcd_data anstelle der UART Ausgabe umbauen. Edit: Wie du für meinen Geschmack überhaupt noch ein bischen zu sehr Copy&Paste programmierst. Wenn ein Teilbereich in deinem Programm funktioniert, dann hast du den sehr oft einfach kopiert und Registerbezeichnungen angepasst anstatt dir zu überlegen, wie du das so formulieren kannst, dass du eine gemeinsame Routine hast, der du in vereinbarten Registern die relevanten Kennwerte hinterlässt und die dann mehrmals benutzt werden kann, in dem man zb für verschiedene Städte die jeweiligen Kennwerte in diese vereinbarten Register kopiert und die Routine aufruft. Mit so einer Textausgabefunktion vereinfacht sich zb in letzter Konsequenz die Ausgabe des Wochentags enorm, weil sich der Start des Wochentags-Textes ja aus der Wochentagsnummer berechnen lässt. Da ist noch viel Potential, wie man das Programm gleichzeitig einfacher und kürzer machen kann und damit dann auch änderungsfreundlicher hinkriegt. So wie du das
:
Bearbeitet durch User
Karl Heinz schrieb: > Das flackert sonst wie Sau! so schlimm ist es auch nicht :P Spaß bei Seite, danke für den Tipp! Karl Heinz schrieb: > Jeder Anzeigemodus wird, > nachdem er seine Anzeige gemacht hat, verlassen und kehrt wieder zu main > zurück. Dort wird dann wieder die Tastenauswertung gemacht und je nach > Modus gehts wieder zurück in den jewiligen Anzeigemodus, der die > aktuelle Uhrzeit EINMALIG wieder auf die Anzeige klatscht. Ist er damit > fertig, gehts wieder zurück zu main, Tastenauswertung und Entscheidung > anhand des Modus, welche Anzeige zu machen ist. So habe ich mir das ja auch gedacht und da kam mir sofort der ext Interrupt in den Sinn, denn die normale Tasterabfrage ist eine Schleife, die DANN ERST weiterspringt, wenn die Taste gedrückt wurde... Also wie schaffe ich es den Taster abzufragen ohne dass er immer rjmp warte_auf_taste ausführt? Da liegt das Problem Karl Heinz schrieb: > AUch solltest du dir mal darüber Gedanken machen, dir eine Funktion zu > schreiben, mit der du fixe Texte ausgeben kannst. Meinst du ich könnte das für die Wochentagsanzeige gebrauchen? Und vielen Dank übrigens, du hilfst mir echt weiter!
Joachim Jakob schrieb: > So habe ich mir das ja auch gedacht und da kam mir sofort der ext > Interrupt in den Sinn, denn die normale Tasterabfrage ist eine Schleife, > die DANN ERST weiterspringt, wenn die Taste gedrückt wurde... Genau das darf natürlich nicht sein! > Also wie schaffe ich es den Taster abzufragen ohne dass er immer rjmp > warte_auf_taste ausführt? > Da liegt das Problem Die Lösung besteht darin, dass man Veränderungen im Tastenzustand feststellt. D.h. du wartest NICHT darauf, dass die Taste eine 0 liefert (oder eine 1). Sondern du vergleichst den Tastenzustand JETZT mit dem Tastenzustand ein paar Mykrosekunden zuvor. Sind die beiden gleich, dann hat niemand am Taster gefummelt. Sind sie aber NICHT gleich, dann ist die Taste gedrückt oder losgelassen worden! http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten
Karl Heinz schrieb: > > http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten Beim ersten Beispiel (das im Tut nicht zuverlässig funktioniert) änderst du die Routine tv wie folgt ab
1 | .... |
2 | mov key_old, temp1 ; bisher war kein Taster gedrückt |
3 | |
4 | loop: |
5 | in key_now, key_pin ; den jetzigen Zustand der Taster holen |
6 | mov temp1, key_now ; und in temp1 sichern |
7 | eor key_now, key_old ; mit dem vorhergehenden Zustand XOR |
8 | mov key_old, temp1 ; und den jetzigen Zustand für den nächsten |
9 | ; Schleifendurchlauf als alten Zustand merken |
10 | |
11 | breq do_work ; Das Ergebnis des XOR auswerten: |
12 | ; wenn keine Taste gedrückt war -> normale weitere Bearbeitung |
13 | |
14 | and temp1, key_now ; War das ein 1->0 Übergang, wurde der Taster also |
15 | ; gedrückt (in key_now steht das Ergebnis vom XOR) |
16 | brne do_work ; |
17 | |
18 | .... |
19 | Tastendruck erkannt. Modus umschalten. Modus, das ist eine 1 oder eine 0 in einem Register |
20 | .... |
21 | |
22 | do_work: |
23 | |
24 | mache die Anzeige einmalig, je nach Modus |
25 | |
26 | .... |
27 | |
28 | rjmp loop ; und wieder nachsehen, ob jemand |
29 | ; an der Taste gefummelt hat |
Bei dir könnte diese einfache Tastenabfrage sogar ganz gut funktionieren, weil die Anzeige relativ lange dauert. Das Problem bei dieser Abfrage besteht ja im Grunde darin, dass der µC (im Tutorialsbeispiel) zu schnell ist. Wodurch das Tastenprellen durchschlägt (und genau das ist auch das Problem bei einer Lösung mit externem Interrupt)
:
Bearbeitet durch User
Joachim Jakob schrieb: >> schreiben, mit der du fixe Texte ausgeben kannst. > > Meinst du ich könnte das für die Wochentagsanzeige gebrauchen? Logo. Oder auch die Städtenamen. Oder auch ein Text, wenn du mal eine Weckfunktion einbaust. Oder ..... Einen fixen Text ausgeben braucht man immer wieder mal. Sowas auf Vorrat zu haben kann nie schaden.
wow, danke für die Hilfe! Ich werde die genannten Sachen in mein Programm einbauen und anschließend wieder hier posten. Der Hinweis mit dem Tastenzustand ist genau das, was ich brauche! Und das mit dem Kürzen und Vereinfachen versuche ich dann auch umzusetzen. Also Danke nochmal und hoffentlich begutachtest du bald mein funktionierendes Programm! :D
Joachim Jakob schrieb: > ich habe zwei posts weiter oben noch einen code gepostet, der meiner > Meinung nach deinen Anforderungen entspricht. Das sieht doch schon nicht schlecht aus. Nur kann deine > Ich verstehe auch was du meinst, aber meiner meinung nach ist das nur > mit einem ext Interrupt zu realisieren, denn die Ausgabe muss doch jede > Sekunde stattfinden, um die Sekunden zu aktualisieren und wenn das > Programm immer mit dem Abfragen des Tasters beschäftigt ist, kann keine > Aktualisierung stattfinden. > So sehe ich das..
Hi Wie viele Anfänger machst du den Fehler, ein Programm nicht aufzuteilen, sondern in große Blöcke alles reinzupacken. Assembler ist zwar geduldig und läßt vieles zu, aber irgendwann verlierst du den Überblick. Versuch mal, deine Main mit einer Event-Steuerung auszustatten. Wie bereits erwähnt, benötigst du dazu das Ereignis "Signal kommt" oder "Signal geht". Wenn du in der Main immer eine Routine aufrufst, die einfach den Status der Eingänge sammelt und in ein Byte ablegt, wird es schon einfacher. Nennen wir sie mal "read_IO" und getreu nach dem Muster EVA (Einlesen Verarbeiten Ausgeben) steht der Aufruf RCALL "Read_IO" am Anfang der Programmschleife. Dort samelst du alle Eingänge ein, drehst eventuell den Logikpegel ( es läßt sich einfacher denken "Taster gedrückt = 1 als Taster gedrückt = 0 bei Tasteranbindung an GND) und legst in einer Variablen "Akt_In" den Status ab. In der nächsten Subroutine prüfst du mit EOR den aktuellen und den letzten Status. So bekommst du die Ereignisse bei einer Änderung mit einer 1 geliefert. Diese 1 verundest du mit ddem neuen Status ( Wechsel von 0 nach 1) oder mit dem alten Status (Wechsel von 1 nach 0). Dieses Ergebnis legst du in einem Eventbyte ab ( Event_To_1 oder Event_To_0). Anschließend wird noch der neue Status in die Ablage kopiert. Ein weiteres Unterprogramm kümmert sich nun um die gesetzten Bits in der Eventvariable. Ist ein Bit gesetzt, so wird der zugehörige Job angestoßen und das Bit gelöscht. Für deine Ausgabe nimmst du einen Puffer, den du entsprechend füllst. Deine Ausgabe greift nun abhängig von Timer auf diesen Puffer zurück. Da ist es egal, ob da die Zeit von Alaska oder dem Äquator drinsteht. Das weist du in den Tasterereignissen zu. Vielleicht hilft dir zusätzlich zum Tutorial dieser Seite ein Beitrag im Forum AVR-Praxis unter der Rubrik FAQ mit dem Thema "keine Angst vor Assember" weitere Lücken schließen. Gruß oldmax
So, habe es jetzt hingekriegt :) Ich würde mich über Tipps freuen!
Wochentagsteil ('Mo', 'Di', 'Mi'...) eindampfen über .DB und indirektem Zugriff via Z-Pointer.
Erstmal Glückwunsch! - Ein weiterer Assembler-Programmierer. >Ich würde mich über Tipps freuen! Na denn: Peter Dannegger schrieb: > Kommentare sind für einen selber da, um auch später noch zu verstehen, > was man mal hingeschrieben hat. > > Sie können aber auch sofort aufzeigen, daß man sich vorher keine > Gedanken über die Funktion gemacht hat. Sie sind sozusagen eine erste > Gütekontrolle. Bei einem Anfänger darf man das natürlich nicht ganz so streng nehmen, aber ...
sprechende Registernamen, wie bei
> .def temp1=r16
also z.B.
.def Sekunden = r20
.def Minuten = r24
Das Programm liest sich leichter, und Tippfehler werden ausgesprochen
selten (wenn man sich bei r24 vertippt, sucht man u.U. lange).
LostInMusic schrieb: > Wochentagsteil ('Mo', 'Di', 'Mi'...) eindampfen über .DB und > indirektem Zugriff via Z-Pointer. Ja, das ist dann der nächwte Schritt der alte Hanns schrieb: > sprechende Registernamen, wie bei > .def temp1=r16 > > also z.B. > .def Sekunden = r20 > .def Minuten = r24 > > Das Programm liest sich leichter, und Tippfehler werden ausgesprochen > selten (wenn man sich bei r24 vertippt, sucht man u.U. lange). Ja, ich bin nunmal schlampig.. Das werde ich auch noch ändern. Es ist so entstanden, weil ich mich immer Schritt für Schritt gesteigert habe und am Anfang habe ich einfach irgendwelche Register ausgewählt^^ der alte Hanns schrieb: > Erstmal Glückwunsch! - Ein weiterer Assembler-Programmierer. > > Ich würde mich über Tipps freuen! > > Na denn: > > Peter Dannegger schrieb: > Kommentare sind für einen selber da, um auch später noch zu verstehen, > was man mal hingeschrieben hat. > Sie können aber auch sofort aufzeigen, daß man sich vorher keine > Gedanken über die Funktion gemacht hat. Sie sind sozusagen eine erste > Gütekontrolle. > > Bei einem Anfänger darf man das natürlich nicht ganz so streng nehmen, > aber ... Ja, auch das werde ich noch einbinden :) Also Danke für die Tipps! Wollt ihr die verbesserte Version dann auch sehen?
@ Joachim Jakob (fhjgch)
>Wollt ihr die verbesserte Version dann auch sehen?
Nur wenn sie WIRKLICH verbessert ist.
Hi Ich hab wirklich ein Problem, mich in deinem Konstrukt zurecht zu finden. Sicher, solange das Programm noch frisch ist, kennst du dich damit aus, aber... laß mal ein paar Tage verstreichen. Hier mal mein Tip, mit dem ich mich bei Assembler auch nach Monaten zurecht finde. Zuerst Kopf.
1 | ;***************************************** |
2 | ;* hier steht die Programmbeschreibung * |
3 | ;* in einem Kommentarfeld * |
4 | ;***************************************** |
5 | Reset: RJMP Init ; Sprung über die IVT |
6 | ;***************************************** |
7 | ;* Abbild der Interrupt Vektor Tabelle * |
8 | ;***************************************** |
9 | ;IVT |
10 | :----------------------------------------- |
11 | Init: ;Initialisierung |
12 | ; Stack initialisieren |
13 | RCALL Init_IO ; IO initialisieren |
14 | RCALL Init_Timer ; Timer initialisieren |
15 | RCALL Init_Usart ; Usart initialisieren |
16 | RCALL Set_Default_Reg ; Registerwerte vorbesetzen |
17 | RCALL Set_Default_VAr ; Variablen vorbesetzen |
18 | ; etc |
19 | |
20 | ;****************************************** |
21 | ;* Schleife Hauptprogramm * |
22 | ;****************************************** |
23 | |
24 | Main: |
25 | RCALL Read_IO |
26 | RCALL Debounce |
27 | RCALL Set_Io_Event |
28 | RCALL Read_Usart |
29 | RCALL Chk_IO_Event |
30 | RCALL Chk_Rec |
31 | RCALL set_Anz |
32 | RCALL Write_IO |
33 | RCALL Send_Data |
34 | RJMP Main |
35 | |
36 | ;***************************************** |
37 | ;* Bereich der Unterprogramme, * |
38 | ;* beginnend mit Initialisierung * |
39 | ;* gefolgt von Leseroutinen * |
40 | ;* Verarbeitung und Ausgabe * |
41 | ;* Am Schluss die Interruptroutinen * |
42 | ;***************************************** |
43 | |
44 | Init_IO: |
45 | .... |
46 | RET |
47 | |
48 | USW... |
Beachte dabei, das du richtig einrückst. Sprungmarken und RET stehen am Anfang der Zeile, alles andere rückst du ca. 2-3 zeichen ein. Das ergibt ein sauberes Bild und eine gute Übersicht. Und ja, noch etwas: gewöhn dir an, die Kommentarzeilen gleich zu schreiben. Du wirst uns für diesen Hinweis irgendwann dankbar sein. Gruß oldmax
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.