mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Verständnisfrage PIC-Stack


Autor: Jens Plappert (Firma: Bei mir und dir.) (gravewarrior)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Cypress (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
GOTOs sind keine Unterprogrammaufrufe! Der Stack wird vollkommen in Ruhe 
gelassen und nur ein neuer Wert in den PC (programm counter) geladen.

Cheers

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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):
    clrf Ziffer1 ; Ziffern auf 0 setzen
    clrf Ziffer2
    clrf Ziffer3

Z1
    movf Zahl,0   ; Zahl nach W holen
    addlw D'156' ; 100 von W abziehen 
                 ; Bei Fragen bitte nachrechnen
    btfsc STATUS, Z ; wenn Zero-Bit nicht gesetzt, nächste Anweisung
                   ; überspringen
    goto Z2      ; also nur zu Z2, wenn die Subtraktion 0 ergab
    
    btfsc STATUS, C 
    goto Z2      ; oder wenn Carry gesetzt ist (= Überlauf oben)

    ; geht sicher auch schöner, nur fällt mir das im Moment nicht 
    ; ein --- es ist ja schon spät

    movwf Zahl   ; Ergebnis zurückschreiben
    incf Ziffer1,1 ; Ziffer1 erhöhen
    goto Z1      ; und weitermachen

Z2
    movf Zahl,0   ; Zahl nach W holen
    addlw D'246' ; 10 abziehen
    btfsc STATUS, Z ; wenn Zero-Bit nicht gesetzt, nächste Anweisung
                   ; überspringen
    goto Z3      ; also nur zu Z3, wenn die Subtraktion 0 ergab
    
    btfsc STATUS, C 
    goto Z3      ; oder wenn Carry gesetzt ist (= Überlauf oben)

    movwf Zahl   ; Ergebnis zurückschreiben
    incf Ziffer2,1 ; Ziffer2 erhöhen
    goto Z2      ; und weitermachen
    

Z3
    movf Zahl,0   ; Zahl nach W holen
    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

Autor: Jens Plappert (Firma: Bei mir und dir.) (gravewarrior)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
M1  incf   zahl, 1          ; Erhöhe Zahl um eins und Speichere in Zahl  
  call   Presettabelle
  call  Anzeigeschleife
        goto    M1

...
Anzeigeschleife
  movlw  D'127'            ; Anzahl Aufrufe Subroutine
  movwf  durchg  

  clrf  PORTE
  clrf  PORTC
  
A1  bsf    PORTE, 0        ; Segment eins aktiv
  movfw  Ziffer1          ; Wert Ziffer 1 laden
  call  BCD            ; BCD-Auswertung
  movwf  PORTC          ; 7-Segmentanzeige beschreiben
  call  WAIT          ; 1ms Warten
  
  bcf    PORTE, 0
  bsf    PORTE, 1          
  movfw  Ziffer2    
  call  BCD
  movwf  PORTC
  call   WAIT
  
  bcf    PORTE, 1
  bsf    PORTE, 2
  movfw  Ziffer3
  call  BCD
  movwf  PORTC
  call  WAIT
  bcf    PORTE, 2
  
  
  decfsz  durchg, F        ; durchgang um eins vermindern, wenn null ist 
                  ; nächsten befehl überspringen
  goto  A1            ; wenn nein gehe wieder zu A1
  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.

Autor: gravewarrior (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jens Plappert (Firma: Bei mir und dir.) (gravewarrior)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jens Plappert (Firma: Bei mir und dir.) (gravewarrior)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hier nochmal der aktuelle code ( in dem die angesprochenen sachen schon 
geändert wurden)

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Jens Plappert (Firma: Bei mir und dir.) (gravewarrior)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Jens Plappert (Firma: Bei mir und dir.) (gravewarrior)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;-)

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Jens Plappert (Firma: Bei mir und dir.) (gravewarrior)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;-)

Autor: Ralf Moshage (ego)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau dir doch mal dises Tutorial an 
:http://www.fernando-heitor.de/component/option,com...
MFG

Ralf

Autor: Jens Plappert (Firma: Bei mir und dir.) (gravewarrior)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DANKE!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.