Nachdem ich nun eine ellenlange Auswertetabelle durch einen Code zur
Berechnung ersetzen wollte, wüet mein uC unkontrolliert herum.
Mich wundert daran das es sich dabei sogar um funktionen handelt, die
garnicht mit dem veränderten modul in zusammenhang stehen.
Mit dem neuen code sendet er mir permanent eine 1 per RS232. Das hat er
mit dem alten nur beim anlaufen und im interupt gemacht.
Die anzeige funktioniert mit dem neuen programm auch nicht.
An dieser Nachricht ist die Neue Version angehängt, in der nächsten die
alte.
Vl.hat ja jemand muse und kann sich das mal ansehen.
greets, Jens
Hallo
Ich kenne mich mit PICs nicht aus, nur soviel: Sowas kann geschehen,
wenn Subroutinen nicht korrekt beendet werden. Vielleicht vergisst du
irgendwo, dem Prozessor zu sagen, er soll die Subroutine verlassen. Dann
rennt er natürlich geradeaus weiter in den unmittelbar darauf folgenden
Code. Oder vielleicht überschreibst du versehentlich die
Rücksprungadresse auf dem Stack.
Gruss
Michael
@mr.chip:
PICs haben keinen Stack im RAM, sondern einen 8-Level Hardware-Stack, so
etwas kann nur passieren falls mehr als 7 Subroutinen-Aufrufe hat (inkl.
Interrupt),
dann wird jeweils die letzte Return-Adresse überschrieben.
Habe mir jetzt den Code nicht angesehen, vielleicht mache ich das
irgendwann.
Es ist im wesentlichen auf folgende Punkte zu achten:
- Hardware-Stack hat nur 8 Level, älteste Return-Adresse wird
überschrieben wenn es mehr als 8 Subroutinen sind.
- ADDWF PCL,F darf nur Adressen innerhalb eines Boundarys von 256
Befehlen anspringen (..00 - ..FF), sonst erfolgt ein Rollover und
die angesprungene Adresse ist 256 Bytes davor!
- Es ist auch auf die 2K Boundarys zu achten und PCLATH zu setzen.
Sieh dir mal das Listing an und schau nach, ob deine Tabelle
über die Boundarys hinausgehen und verschriebe die Tabelle mit
ORG an eine passende Stelle.
Noch ein Tipp: Du kannst 5 Befehle in deiner Delay-Schleife
einsparen, indem du CALL DUMMYLABEL (DUMMYLABEL steht bei
irgendeinem RETURN) und GOTO $+1 machst.
Ich würde die Anfangszeilen der Tabellen per org-Befehl
auf volle 100er Adressen legen.
Die Speicherersparnis wiegt den Ärger nicht auf, wenn durch
Seitenüberschreitung bei Call mit zu grossem Wert in W
irgendwo hin gesprungen wird.
hm, also irgendwie versteh ich jetzt nur die hälfte von dem was ihr mir
sagt. das mit der tabell und dem pc leuchtet mir ein. jedoch ist ja die
tabelle in beiden versionen gleich und auch an gleicher stelle.
naja, das frag ich mich auch so langsam. wobei c bestimmt nicht mein
fall ist. ich denke da eher an mikrobasic. mal schauen. solche
krückenprobleme gehen mir irgendwie so langsam aufn sender mit asm...
Hey, vielen herzlichen dank. kanns leider erst heute abend ausprobieren.
könntest du mir bitte erklären was du geändert hast (das sehe ich ja
noch), aber vor allem WARUM welche änderungen vorgenommen wurden?
auf jeden fall schon mal fett-merci für deine Mühe!!!
Im Anhang ist ne kurze Routine zur Umrechnung
Hex-Dez.
Besorg dir am besten das Datenblatt,
im Kapitel 2.3 steht was zur Problematik mit den
Tabellen ( "computed goto").
Ein Blick in die Befehlsbeschreibung lohnt sich auch,
die sub-Befehle z.B. sind tückisch, weil man aus dem Namen nicht
erkennen kann, was wovon abgezogen wird.
Gruss
Digger
bin jetzt endlich daheim und fang jetzt an mir das im datenblatt
durchzulesen.
Dein letzter post hatter aber keinen anhang, oder hab ich da was falsch
verstanden?
Auf jeden fall schonmal VIELEN DANK!
das Problem mit den goto-tabellen (addwf PCL,f) kenne ich. Kann es aber
in meinem fall damit zusammenhängen? Die Version die mläuft hat ja an
exakt gleicher codestelle die tabelle. verteilt der compiler eigentlich
meine bytes gut, mdas heisst z.b. meine startroutine geht bis 0x44,
meine tabelle geht ab 100 los bis 110, füllt mir der compiler dann den
ganzen platz zwischendrin mit den "unkritischen" befehlen auf, oder ist
das dann wieder voll-linear und ich hab knapp 60 byte verschenkt wenn
ich nicht aufpasse?
In meiner preset-routine, kann da das computed goto-problem eigentlich
auch eine falle sein? Dachte das wäre immer nur bei tabellenblöcken
möglich, da ich ja hier nicht mit addition sondern direkt zu einem label
mspringe.
Last but not least: umschifft ein guter Hochsprachencompiler solche
stolpersteine von alleine?
Mir ist der mikroBasic sehr ins Auzgegefallen und ich überleg mir vl.
vor dem nächsten Projekt sowas zu holen (mit dem hier bin ich insgesamt
schon zu weit in ASM, um nochmal alles neu zu machen).
greets, Jens
Lieber Dieter Werner, vielen Dank erstmal, die umgeschriebene Routine
Funktioniert wunderbar. Werd mich nacher nochmal damit befassen warum
die meinige dies nicht tat und vielleicht mit einer Verständnisfrage
nochmal zutage treten.
greets, Jens
Ok, ich habe meine fragen zusammen:
Das Carry-bit: Ich dachte das ist immer 0 und wird beim Überlauf
gesetzt.
Deinem Code entnehme ich, dass es wohl im "Ruhezustand" auf 1 steht und
gelöscht wird. Stimmt das?
Was mir noch auffällt: du fragst das Z-Flag nicht mehr mit ab. Das Rührt
daher dass du immer zuerst die operation ausführst und durch das
ausgleichende addwf wieder alles "Richtigrückst", weswegen man sich das
explizite abfragen des Z-Bits sparen kann, right?
Wie wäre es nun mit Z-Bit, ist das dann auch immer 1 und wird gelöscht
wenn das Ergebnis 0 gibt, oder ist es im Ruhezustand auf 0?
Ich denke mein Hauptsächlicher Fehler war wohl das falsche abfragen des
C-flags, oder?
Das Z-Flag war einfach nur unnötig, aber mit der richtigen abfrage
(sollten denn meine aktuellen vermutungen stimmen), hätte es auch mit
meiner (wenn wohl auch umständlichen) version funktioniert, oder?
Freue mich auf Antworten zu diesen fragen, das würde mich
Verständnismäßig ein gutes stück weiterbringen!
Thanks!
hab gerade im datenblatt nachgeschaut. Die Note von 2.5 verstehe ich
nicht so ganz.
Heisst das (zusammen mit der bit-erklärung weiter oben, die ja für c und
z eine 0 im ruhezustand definiert), dass bei additionen das Z und C-Bit
im "Normalfall"(also ohne Null oder Überlauf)=0 sind
UND, dass sie bei subtraktionen im "Normalfall"(ebenso ohne Null oder
Überlauf) aber 1?
sehe ich das richtig so? Das ganze ist ein wenig verwirrend.
greets, Jens
Hallo Jens, ich versuch mal das etwas zu verdeutlichen.
Als erstes war kurz nach "startup" ein Tippfehler
MOVFW ADCON1 ; nach AD-Register schreiben
das muss natürlich MOFWF sein sonst wird ja gelesen.
Die Umwandlungsroutine hat Pseudotetraden (Werte zwischen A und F)
zurückgegeben, dann wird nicht IN sondern HINTER die BCD Routine
gesprungen und das Programm rastet aus.
Das carryflag hat keinen "Ruhezustand" sondern wird nur bei
verschiedenen Operationen gesetzt oder gelöscht. Bei Addition ist
bekanntlich carry gelöscht wenn KEIN Übertrag und gesetzt wenn Übertrag
entsteht.
Bei einer Subtraktion ist es (zumindest bei PIC) genau umgekehrt, die
Abfrage war also falsch.
Es gibt sicherlich elegantere Lösungen für die HEX in BCD Umwandlung
aber die von mir verwendete finde ich am übersichtlichsten.
Da wird halt ganz einfach so oft 100 abgezogen und das 100er
Ergebnisregister um eins erhöht wie carry auf 1 bleibt. Wenn carry 0 ist
wird die letzte 100 (die den Über- oder besser Unterlauf verursacht hat)
wieder addiert und das Ganze wiederholt sich mit den 10ern.
Die Abfrage des Zeroflag erübrigt sich da das von der Routine richtig
verarbeitet wird.
Vielleicht ist jetzt einiges etwas klarer geworden.
P.S.
Ohne Simulator tut man sich schon etwas schwer mit dem Verständnis,
welches Entwickliungssystem verwendest Du denn ?
Dieter
Sorry, hier nochmal der Anhang.
>füllt mir der compiler dann den>ganzen platz zwischendrin mit den "unkritischen" befehlen auf
Hängt vom Compiler ab, wahrscheinlich füllt er mit "FF" auf.
>Das Carry-bit: Ich dachte das ist immer 0 und wird beim Überlauf>gesetzt.>Wie wäre es nun mit Z-Bit, ist das dann auch immer 1 und wird gelöscht>wenn das Ergebnis 0 gibt, oder ist es im Ruhezustand auf 0?
Die meisten Befehle verändern die Statusbits nicht,
das ist von Vorteil, da man in Programmverzweigungen
oft mehrfach abfragen muss.
Das Z-Flag ist 1, wenn das Ergebnis Null ist.
Ein gesetztes Carry steht nach Addition für einen Übertrag,
nach Subtraktion ist es umgekehrt.
MfG
Digger
Ok, das mit dem C und Z-Flag ist mir jetzt klar. Wobei mich etwas
aufregt dass in meinem buch nicht an entsprechender stelle auf diesen
umstand beim C-Flag hingewiesen wird. Wenn man sowas in einem Buch
liest, denkt man man hats verstanden und kommt auf sowas nie.
Das mit den Pseudotetraden verstehe ich nu nich so ganz, vor allem der
Bezug zu Hex. gerechnet wird ja alles Binär. Wie kommen diese
Pseudotetraden (so heissen die Hexwerte für 10-16?) zustande? Was hat
denn genau dafür gesorgt?
Vielen dank auch noch für die PDF, einiges ist heute schon klarer
geworden, und so langsam frage ich mich, ob das echt alles so sein muss.
Wie sind da die erfahrungen mit Hochsprachen? Ersparn die einem sowas?
greets, Jens
Das Ergebnis (Pseudotetrade) entstand durch die falsche Abfrage des
carryflags.
Versuch doch mal einen Simulator zum Laufen zu bringen und hangel Dich
durch den Code.
Unter Windows bietet sich da die MPLAB IDE von Microchip an.
Leider sind das ca. 40MB zum download, also nur für Breitband Anschluss
geeignet.
EDIT
Hochsprachen verlagern die Missverständnisse auf eine höhere Ebene, da
gehts halt z.B. um ein falsches Ergebnis durch Addition einer signed und
einer unsigned Variablen und nicht mehr um Flags im Controller.
Ich benutze ja MPLAB IDE, aber ich hab keine Ahnung wie das mit dem
Simulator so funktioniert. Habe da bis jetzt auch noch keine wirklich
gute Einleitung zu gefunden.
Ansonsten: Das Hochsprachen auch Probleme haben, und man nicht
"kinderleicht" Programmieren kann ist mir schon klar. Nur kommt man da
in der Regel wenn man Typenstreng arbeitet doch eher auf die Fehler wie
z.b. Das mit dem C-Flag.
Ich denke, man umgeht diese ganz versteckten gemeinheiten, oder lieg ich
da falsch.
Mir geht es aber Primär auch nicht darum, vor allem Problemchen
wegzurennen (einiges habe ich ja mittlerweile auch schon selbst
geschafft), sondern ums flüssigere Programmieren. Sich also mehr auf die
Fragestellung als auf Flags zu Konzentrieren. Meinst da ist mikroBasic
ein weg dazu?
Basic-Syntax ist mir allgemein um welten lieber als C.
Man kann ja Subroutinen auch in ASM einbinden, oder?
Mich reizen halt wirklich so sachen wie RS232 "Klassen" wenn man das so
nennen kann, oder auch vordefinierte Module für zumindest
Standarddisplays.
Der mikroBasic bietet da halt schon ne recht große bibliothek.