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
hmm, bins nochmal durchgegangen, aber ale subprogramme werden beendet.
@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.
Ich weiß, dass löst jetzt nicht dein Problem, aber warum ASM und nicht C?
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...
kann nich mitm debuger umgehen und hab leider auch noch nirgends ne verständliche einleitung dazu gefunden. wäre für nen link sehr dankbar
Versuch's mal mit der Version, da ist die Routine "Presettabelle" so korrigiert dass sie jetzt auch funktioniert.
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!
noch eine letzte frage hinterher: was genau hat denn das "Hängen und rumspinnen" des Controllers ausgelöst?
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
Und hier noch eine etwas ausführlichere Beschreibung der Befehle als im Datenblatt. 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.
Schau dir doch mal dieses Tutorial zu MPLAB Simulation 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.