Hi Leute, mal ne frage: Ich darf ja nur max 8 unterprogramme schachteln. Ist ein Unterprogramm nun nur etwas, was ich per call aufrufe oder auch durch goto bedignte sprünge? falls gotos auch als unterprogramme zählen, wie könnte ich denn dann so eine abfrage wie im angehängten programm ansonsten gestalten? falls jemand zufällig einen sonstigen fehler entdeckt, bin ich sehr dankbar, aber ich kämpf mich auch gern alleine durch. das programm soll eigentlich auf einer 7-segmentanzeige hochzählen. zeigt aber nur 001 an und das wars. irgendwas läuft halt ned richtig. thx and greets, Jens
Hi, GOTOs sind keine Unterprogrammaufrufe! Der Stack wird vollkommen in Ruhe gelassen und nur ein neuer Wert in den PC (programm counter) geladen. Cheers
Betrifft nur call: Call Subroutine. First, return address (PC+1) is pushed onto the stack. The eleven-bit immediate address is loaded into PC bits <10:0>. The upper bits of the PC are loaded from PCLATH. CALL is a two-cycle instruction. Anstatt movlw B'00000000' movwf PORTA movwf PORTB movwf PORTC movwf PORTD movwf PORTE kannst Du clrf PORTA clrf PORTB clrf PORTC clrf PORTD clrf PORTE nehmen --- einen Befehl und ein wenig Zeit gespart. Dein Konstrukt zum Ausgeben der Ziffern ist doch ein wenig umständlich. Es geht hier um Pressetabelle. Was hältst Du denn von einem Konstrukt wie (ungetestet):
1 | clrf Ziffer1 ; Ziffern auf 0 setzen |
2 | clrf Ziffer2 |
3 | clrf Ziffer3 |
4 | |
5 | Z1 |
6 | movf Zahl,0 ; Zahl nach W holen |
7 | addlw D'156' ; 100 von W abziehen |
8 | ; Bei Fragen bitte nachrechnen |
9 | btfsc STATUS, Z ; wenn Zero-Bit nicht gesetzt, nächste Anweisung |
10 | ; überspringen |
11 | goto Z2 ; also nur zu Z2, wenn die Subtraktion 0 ergab |
12 | |
13 | btfsc STATUS, C |
14 | goto Z2 ; oder wenn Carry gesetzt ist (= Überlauf oben) |
15 | |
16 | ; geht sicher auch schöner, nur fällt mir das im Moment nicht |
17 | ; ein --- es ist ja schon spät |
18 | |
19 | movwf Zahl ; Ergebnis zurückschreiben |
20 | incf Ziffer1,1 ; Ziffer1 erhöhen |
21 | goto Z1 ; und weitermachen |
22 | |
23 | Z2 |
24 | movf Zahl,0 ; Zahl nach W holen |
25 | addlw D'246' ; 10 abziehen |
26 | btfsc STATUS, Z ; wenn Zero-Bit nicht gesetzt, nächste Anweisung |
27 | ; überspringen |
28 | goto Z3 ; also nur zu Z3, wenn die Subtraktion 0 ergab |
29 | |
30 | btfsc STATUS, C |
31 | goto Z3 ; oder wenn Carry gesetzt ist (= Überlauf oben) |
32 | |
33 | movwf Zahl ; Ergebnis zurückschreiben |
34 | incf Ziffer2,1 ; Ziffer2 erhöhen |
35 | goto Z2 ; und weitermachen |
36 | |
37 | |
38 | Z3 |
39 | movf Zahl,0 ; Zahl nach W holen |
40 | movwf Ziffer3 ; und als Ziffer3 speichern |
Mit Umlauten und Sonderzeichen in den Label-Namen wäre ich persönlich vorsichtig, allerdings weiß ich nicht, ob das vielleicht doch unproblematisch ist. Mit 'movfw' würde ich vorsichtig sein, da es vom Compiler abhängt, wie er damit umgeht. In der Doku heißt es: MOVF Move f Syntax: [ label ] MOVF f,d Operands: 0 ≤ f ≤ 127 d ∈ [0,1] Operation: (f) → (destination) Status Affected: Z Description: The contents of register f are moved to a destination dependant upon the status of d. If d = 0, destination is W register. If d = 1, the destination is file register f itself. d = 1 is useful to test a file register, since status flag Z is affected. Dein Programm läuft übrigens aus folgendem Grund nicht richtig: M1 incf zahl, 1 ; Erhöhe Zahl um eins und Speichere in Zahl call Presettabelle M2 call Anzeigeschleife es fehlt ein simples goto, um wieder zu M1 zu kommen. Effektiv wird es zum das nachfolgende BCD einen Return zu irgendeiner Adresse ausführen und dann passieren komische Dinge. Gruß, Florian
Danke für deine Ausführlichen erklärungen. habe zwar jetzt auf die schnelle noch nicht alles verstanden, werds mir aber heut abend nochmal genauer anschauen. aber ein goto auf M1 habe ich ja in der anzeigeschleife. oder meinst da müsste trotzdem noch eins drunter?
Habe ich übersehen. Allerdings ist das kein goto auf M1, sondern auf MAIN und da wird die Zahl wieder zurückgesetzt. Stattdessen sollte allerdings ein retlw da hin, da Du die Routine ja mit call aufrufst. Mir ist nicht ganz klar, was Du mit movlw D'128' ; Lade Grenzwert in Akku subwf zahl, 0 ; Subtrahiere W von Zahl und Speichere in W btfsc STATUS, Z ; Überspringe nächsten Befehl wenn nicht null goto MAIN ; wieder von ganz vorne beginnen bcf STATUS, Z ; Zero-Bit zurücksetzen bezwecken willst. In Deiner Schleife (wenn Sie denn da wäre) um M1 wird die Zahl hochgezählt und Anzeigeschleife stellt die Ziffern eine bestimmte Zeit dar. Eigentlich hat die doch nichts mit der Zahl an sich zu tun. Also
1 | M1 incf zahl, 1 ; Erhöhe Zahl um eins und Speichere in Zahl |
2 | call Presettabelle |
3 | call Anzeigeschleife |
4 | goto M1 |
5 | |
6 | ... |
7 | Anzeigeschleife |
8 | movlw D'127' ; Anzahl Aufrufe Subroutine |
9 | movwf durchg |
10 | |
11 | clrf PORTE |
12 | clrf PORTC |
13 | |
14 | A1 bsf PORTE, 0 ; Segment eins aktiv |
15 | movfw Ziffer1 ; Wert Ziffer 1 laden |
16 | call BCD ; BCD-Auswertung |
17 | movwf PORTC ; 7-Segmentanzeige beschreiben |
18 | call WAIT ; 1ms Warten |
19 | |
20 | bcf PORTE, 0 |
21 | bsf PORTE, 1 |
22 | movfw Ziffer2 |
23 | call BCD |
24 | movwf PORTC |
25 | call WAIT |
26 | |
27 | bcf PORTE, 1 |
28 | bsf PORTE, 2 |
29 | movfw Ziffer3 |
30 | call BCD |
31 | movwf PORTC |
32 | call WAIT |
33 | bcf PORTE, 2 |
34 | |
35 | |
36 | decfsz durchg, F ; durchgang um eins vermindern, wenn null ist |
37 | ; nächsten befehl überspringen |
38 | goto A1 ; wenn nein gehe wieder zu A1 |
39 | retlw D'0' |
So sollte (auch mit Deiner komplizierten Auswertung) eigentlich hochgezählt und angezeigt werden. Übrigens nebenbei: Du musst das Zero- oder Carry-Flag nicht jedesmal zurücksetzen, da Die Anweisung wie z.B. subwf das Fläg überschreiben.
ok, danke soweit. das ich das flag nich zurücksetzen muss is auch gut zu wissen (habs mir fast gedacht, wollt aber auf nummer sicher gehen) die zusätzliche Subtraktion/auswertung in meiner anzeigeschleife rührt daher das es ab 128 wieder mit 0 anfangen soll, also ganz zurück zur main. die auswertung is deshalb so aufwändig, weil da später noch einiges in die einzelnen parts soll (also noch EEPROM-Variablen setzen, EDIT-Modus bedienen usw. das is nur das ganz grundsätzliche skellet zum ausprobieren. is dann ium endeffekt natürlich auch was ganz anderes als n programm das von selbst rumzählt ;-) vielen dank auf jeden fall! greets, JEns
also irgendwie ändert sich auch durch das temporäre abschalten des abfragens nach der programmnummer in der anzeigeschleife und nach dem einfügen des fehlenden gotos auch nichts. schon seltsam. greets, Jens
hier nochmal der aktuelle code ( in dem die angesprochenen sachen schon geändert wurden)
Also du siehst immer noch 001? Ich kann Dir nur empfehlen, den Code mal in der MPLAB IDE durchzusteppen. Da wirst Du das Problem sehen. Nochmal zu Deiner Abfrage: Wenn du wirklich einzelne Label brauchst, dann würde ich das so ähnlich wie Deine Funktion BCD (hast Du vermutlich aus dem Netz, oder?) machen, also etwa so: Pressetabelle clrf Ziffer1 clrf Ziffer2 clrf Ziffer3 movf zahl, W addwf PCL,f goto Null goto Eins ... Dann aber aufpassen, dass ungültige Werte vorher aussortiert werden (also Werte > Deines letzten Labels). Und so ungefähr dann weitermachen: Null movlw D'0' movwf Ziffer1 retlw D'0' Eins movlw D'1' movwf Ziffer1 retlw D'0' Wenn 001 angezeigt wird, heißt das erstmal, dass die Funktion Anzeigeschleife soweit läuft (es werden ja nacheinander die Segmente angesteuert). Jetzt könnte es entweder sein, dass die Funktion nicht verlassen wird (Endlosschleife) oder Deine Auswertung nicht richtig funktioniert. Hast Du das mal mit der von mir vorgeschlagenen Auswertung probiert?
die von dir vorgeschlagene variante hab ich noch nicht durch. ja, die BCD-tabelle ist recht eng an spruts variante angelehnt. Welchen vorteil hat deine varinte der abfrage denn genau? weniger code, oder? und eine übersichtlichere tabelle, oder? Das mit dem durchsteppen ist so ne sache. ich hab auch schon dran gedacht, aber keine ahnung davon wie. gibt es da irgendwo ne verständliche beschreibung?(vielleicht sogar auf deutsch?) das wäre mir ne rießen-hilfe. als elektroniker kann ich mit meinen messgeräten umgehen, dann würd ich auch gerne als "programmierer" (nennen wirs elektroniker mit notwendigem übel ;-) ) debuggen und selber suchen können. Auf jeden fall mal vielen vielen dank für deine hilfe!
Die Abfrage-Variante hat deutlich weniger Code. OK, es kommt darauf an, was Du überhaupt am Ende machen möchtest aber der Speicherplatz im PIC ist endlich. Ich habe jetzt lange schon nichts mehr mit PICs gemacht, aber ich meine mich erinnern zu können, dass man in der IDE einfach auf Debug stellen konnte und dann den PIC am Rechner simulieren konnte. Ich meine, das wäre alles mit der MPLAB IDE gegangen. Wenn Du die sowieso benutzt, dann hast Du doch bestimmt schon die Device-Einstellungen vorgenommen und so sollte das kein großen Problem sein. Was Anleitungen in Deutsch angeht: Es hat sich im Laufe der Zeit in vielen Bereichen die englische Sprache etabliert, um so einen weiteren Kreis von Menschen anzusprechen. Wer heutzutage des Englischen nicht oder nur schlecht mächtig ist, hat leider schlechte Karten (ich sehe das an meinen Eltern). Leider gibt es aber auch immer mehr Leute, die der deutschen Sprache, obwohl sie Muttersprachler sind, nicht mächtig sind (auf meinem Weg zum Einkaufen muss ich an einer Fahrschule vorbei, die auf Ihrer Scheibe groß 'Außbildung' stehen hat --- grausam), aber das ist ein anderes Thema. Ich könnte leider nur soetwas anbieten: http://ww1.microchip.com/downloads/en/DeviceDoc/51410b.pdf Auf Deutsch ist weniger zu finden: http://www.fh-sw.de/sw/fachb/et/halbl/ProjektMux/mux.html Da steht aber auch etwas zum Thema Debugging.
vielen dank! das mit dem englisch is mir eigentlich auch klar. verdien ja meine brötchen auch in der elektronik. auf deutsch (sofern vorhanden) tut man sich eben doch etwas leichter. aber danke für die links! PS: Bedienungsanleitungen auf Niederländisch rulen ;-)
Mir ist es auch schon häufiger passiert, dass ich deutsche E-Mails auf englisch beantwortet habe. Wenn man jeden Tag englisch korrespondiert, fällt einem das irgendwann nicht mehr auf, was allerdings nicht bedeutet, dass man nicht auch das ein oder andere Mal zum Wörterbuch greifen muss, wenn es um etwas 'Branchenfremdes' geht.
Ich habs! Danke, das durchsteppen hat echt geholfen. ich hab zwar noch nicht den dreh raus mir beim steppen variablen anzeigen zu lassen, oder irgendwie einfach alles als breakpoint zu markieren, aber das einfache steppen und zusehen hat mich draufgebracht. der fehler lag in der presettabelle. bei wert null war alles noch perfekt, aber ab wert eins habe ich ausversehen (und per C und P dann natürlich ab dort überall) statt zahl und zahlh auf einmal zahl und zahl subtrahiert. das das natürlich immer wahr ist und deswegen immer eins als richtig erkannt wird ist klar ;-) naja, als anfänger muss man durch sowas durch. aber mit dem debugen muss ich mich echt noch etwas mehr beschäftigen. da kommt man wirklich gut vorwärts mit (auch wenn die bedienung recht unübersichtlich ist) DANKE auf jeden fall mal wieder an dich/euch. Finds echt klasse, dass man hier noobs so gut zur seite steht ;-) baut doch mal n bissel e-gitarren-equipment, da kann ich dann helfen ;-)
Schau dir doch mal dises Tutorial an :http://www.fernando-heitor.de/component/option,com_remository/Itemid,31/func,fileinfo/id,1/ MFG Ralf
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.