Archiv verlassen und diese Seite im Standarddesign anzeigen : Divisionsproblem
Import-Script
27.09.2003, 00:56
Hallo <BR> <BR>Kann mir da vielleicht jemand bitte einen kleinen Tipp geben? <BR> <BR>Jetzt will ich mir einen Frequenzzähler basteln, nur das Programm hat einen Fehler. <BR>Das Prinzip ist folgendes: <BR>Counter 1 als Zähler und Counter 2 <BR>erzeugt jede Sekunde Interrupt und gibt Zählerstand aus.(Siehe Code) <BR>Nur genau in diesem Code ist das Problem <BR>Beim Berechnen der Stellen ist immer Fehler bei der Ausgabe. <BR>Sollte zb 128 auf Display stehen, so steht 1<8. <BR>Also ist sozusagen ein Offset von 10 vorhanden, obwohl ich die Mathematikroutine von <BR>Batronix verwende (16bit Division unsigned). <BR>Und bei zb 1227 steht 1<<7. <BR> <BR>Könnt Ihr mir da bitte helfen? <BR>Wie immer bin ich da Ratlos. <BR> <BR>Die Formatierung ist leider im Forum nicht sehr übersichtlich, darum auch als TXT beigefügt. <BR> <BR> <BR> <BR> <BR> <BR>; Interruptbehandlungsroutine Timer 1 <BR>timer1_int: <BR> <BR> <BR> <BR> mov TL1, #TL1PRE <BR> mov TH1, #TH1PRE <BR> djnz timer1_ext24,timer1_int_label <BR> mov timer1_ext24,#TX1PRE <BR> acall timer1_int_label <BR> <BR> <BR> <BR>mov SpeicherH,TH0 ;Dividend aus Zähler in Register für Bearbeitung kopieren <BR>mov SpeicherL,TL0 <BR>mov TL0,#0 ;Zähler zurücksetzen <BR>mov TH0,#0 <BR>;Zehntausender ;Zehntausender <BR>berechnen <BR>mov r4,SpeicherH ;Zaehlerstand in benötigte Register fuer Division laden <BR>mov r5,SpeicherL <BR>mov R6,#39 <BR>mov R7,#16 <BR>call div16u <BR>mov Zehntausender,R5 <BR>call regclear ;Register auf 0 setzen <BR>;Tausender ;Tausender berechnen <BR>mov r4,SpeicherH ;Zaehlerstand in benötigte Register fuer Division laden <BR>mov r5,SpeicherL <BR>mov R6,#3 <BR>mov R7,#232 <BR>call div16u <BR>mov tausender,R5 <BR>call regclear <BR>;Hunderter ;Hunderter berechnen <BR>mov r4,SpeicherH ;Zaehlerstand in benötigte Register fuer Division laden <BR>mov r5,SpeicherL <BR>mov R6,#0 <BR>mov R7,#100 <BR>call div16u <BR>mov hunderter,R5 <BR>call regclear <BR>;Zehner ;Zehner berechnen <BR>mov r4,SpeicherH ;Zaehlerstand in benötigte Register fuer Division laden <BR>mov r5,SpeicherL <BR>mov R6,#0 <BR>mov R7,#10 <BR>call div16u <BR>mov zehner,R5 <BR>;einer ;Einer aus Rest ermitteln <BR>mov einer,R7 <BR>call regclear <BR> <BR> <BR>call lcd_clear ;LCD löschen <BR>mov acc,zehntausender ;Anfang der Ausgabe der Werte auf Display <BR>add a,#48 ;48 hinzuzählen, um auf ASCII CODE zu kommen <BR>call lcd_printc ;Wert aus ACC auf Display schreiben <BR>mov a,tausender <BR>add a,#48 <BR>call lcd_printc <BR>mov a,hunderter <BR>add a,#48 <BR>call lcd_printc <BR>mov a, zehner <BR>add a,#48 <BR>call lcd_printc <BR>mov a,einer <BR>add a,#48 <BR>call lcd_printc ;Ende der Displayausgabe <BR> <BR> <BR> <BR>timer1_int_label: <BR> reti <BR> <BR>mfg hannes<!--attachment: FZaehler-8925.txt*mime_txt.gif*text/plain*2.5*FZaehler*FZaehler%2etxt --><center><table border=1><tr><td><img src="http://progshop.com/elektronik/diskussion/icons/mime_txt.gif" align=left alt="text/plain">FZaehler<br><a href="http://progshop.com/elektronik/diskussion/messages/4982/FZaehler-8925.txt" target="_blank"><b>FZaehler.txt</b></a> (2.5 k)</td></tr></table></center><!--/attachment-->
Import-Script
27.09.2003, 19:52
Hi <BR>wenn ich in deinen Code mir die ersten 5 Zeilen ansehe frag ich mich: wie kommt denn dein Proggi überhaupt zu deinem "Eigenen Teil" du hast ja immer das acall T1_in_label drinne! <BR>MFG <BR>PS: Sonst sieht dein Prog recht vernünftig aus, ich habe selbst vor nem halben Jahr nen Frequenzzähler gebaut aber mit selbst erdachten Divisionsroutinen (wusste gar net dass es hier so was gibt)
Import-Script
27.09.2003, 21:19
Hallo <BR> <BR>Gute Frage, wie der da eigentlich hinkommt zu meinem Teil, nur es funktioniert (Bis eben auf den beschriebenen Fehler) <BR> <BR>Die Grundstruktur wurde mit dem Tool von Erik Buchmann erstellt, und eben genau an der Stelle wo mein Teil steht soll er lt, generiertem Code auch stehen, nur warum da immer Rechenfehler drinnen sind ist mir nicht klar. <BR> <BR>mfg <BR>hannes
Import-Script
27.09.2003, 21:30
Ich benutze auch das Tool von Erik Buchmann , aber man muss den Code ein bisschen umschreiben . <BR>Es passt nicht unverändert ins Batronix Progstudio . <BR>Ist eh immer besser , wenn man das versteht , was man macht . <BR>
Import-Script
27.09.2003, 22:58
Hallo <BR> <BR>Ich benutze RIDE von Raissonance (oder so ähnlich). <BR>Schon klar, daß es nicht schlecht ist, wenn man versteht, was man macht, aber als Grundgerüst ist es wirklich praktisch. <BR>Da dürfte allerdings ein kleiner Bug drinnen sein, mit den Startadressen, die muß man vertauschen (Interruptaufrufe). <BR> <BR> <BR>Jetzt hab ich schon ein paar Beiträge zu diesem Thema bekommen, nur leider ist keiner auf mein Problem mit der Division eingegangen. <BR>Bitte, was hts denn da? <BR> <BR>mfg <BR>hannes <BR>
Import-Script
28.09.2003, 11:17
Ja, um noch mal am Divisionsfehler vorbei zu antworten: <BR>Der Prozessor läuft an, beginnt mit timer1_int:, ruft dann timer1_int_label auf, kehrt zurück - allerdings nicht mit ret, sondern mit reti - und zwar zurück zu dem Punkt, wo er hergekommen ist, und das ist acall timer1_int_label. Er macht also mit dem nächsten Befehl nach dem acall weiter, und das ist das Hauptprogramm. Am Ende des Hauptprogramms macht er dann wieder ein reti, was vermutlich den Stack durcheinander bringt. <BR>Warum rufst du das reti mit einem acall auf? Würde nicht gehen: <BR> <BR>ljmp main_start <BR> <BR>timer1_int: <BR>mov TL1, #TL1PRE <BR>mov TH1, #TH1PRE <BR>djnz timer1_ext24,timer1_int_label <BR>mov timer1_ext24,#TX1PRE <BR>timer1_int_label: <BR>reti <BR> <BR>main_start: <BR>; Hier dann das Hauptprogramm <BR> <BR>Übrigens, ich glaube, das djnz kann auch nur relativ springen, d.h. max. 128 Bytes vor oder zurück. Vielleicht überschreitest du damit die Grenze, denn das timer1_int_label ist ja doch ein Stück weit weg. <BR>
Import-Script
28.09.2003, 11:23
Uh, ich glaube, ich habe dein Programm total missverstanden. Gehört die Division und die Displayanzeige noch zur Interruptroutine dazu? Entschuldigung.
Import-Script
28.09.2003, 17:14
Johann, <BR> <BR>da du nur ein teil deines programmes zeigst ist <BR>es nicht leicht etwas dazu zu sagen. <BR>ich kann dir aber raten kleine pausen in die displayroutinen einzubauen....hast du 24Mhz..? <BR> <BR>bier: djnz spaten,bier <BR>wobei spaten 'irgend' ein register sein kann.. <BR>diese routine geht auch mit rotwein. <BR> <BR>edgar.<img src="http://progshop.com/elektronik/diskussion/clipart/wink.gif" border=0>.200
Import-Script
06.10.2003, 13:02
so so, immer ein Offset von 10...<img src="http://progshop.com/elektronik/diskussion/clipart/smile.gif" border=0> <BR> <BR>Nun bin ich nicht der 8031/51 Pabst, aber wenn da eine Routine vorhanden ist, die <BR>divu(16Bit) = HighByte(8Bit) + LowByte(8Bit) <BR>liefert, dann tut sie das im 16er bzw. im 256er System HEX!!! und nicht BCD mässig im 10er System, wie Du schreibst <BR>Mov Tausender... <BR>Mov Hunderter... <BR>Mov Einer <BR> <BR>Korrekt wäre: <BR>Mov 16Quadrater.. <BR>Mov 16er.. <BR>Mov Einer.. <BR> <BR>Eine DIVBCD(4Nibble) --> BCDHI(2Nibble) BCDLO(2Nibble) musst Du Dir ggf. selbst schreiben. Das geht im Prinzip genauso wie die "batronixinterne" Routine, nur musst Du den Prozessor in den BCD=10er Mode setzen (hoffe das kann der 80xx???), weil dann ein Carry bei Überlauf 10 bereits gesetzt wird. Der 68000er z.B. kann ABCD, SBCD und NBCD (also Add Sub und Neg-BCD) von Haus aus. <BR>Trotzdem wirds da schon hakelig mit der Programmierung; - auch da gibt es Bibliotheken für; klar. <BR>Andere Idee: Tabelle: Wird leider recht gross, 256*256 Byte *2 - also 2* 64kB =2*(271000er Eprom), da mit 16Bit Index rein (obere8 Dividend, untere 8 Divisor) und adressieren, dann im ersten EPROM untere 4Bit die zugehörenden Einer, obere 4Bit=10er, im zweiten Eprom untere 4 Bit = 100er, obere 4 Bit = 1000er direkt rausziehen, und weil´s so schön war und man BCD will (wer BCD will muss Bits investieren) braucht´s noch ein drittes Eprom (4Bitter gibt es nicht, also bleibt das halb leer) für die 10000er Stelle. <BR>Macht nix, Speicher ist billig... -- dafür liefert das Teil in 100ns ein Ergebnis; wenn´s also schnell gehen muss...
Import-Script
21.10.2003, 22:27
hi <BR> <BR>wie kommt das programm zum eigenen teil? <BR>na so: <BR> <BR>-interrupt = rücksprungadresse auf dem stack <BR>-acall timer1_int_label = adresse vom 1.mov-befehl auf dem stack <BR>-sprung zu timer1_int_label <BR>-reti = letzte adresse vom sack (die vom MOV-befehl) -> PC <BR>- weiter bei adresse in PC (MOV-befehl) <BR>-eigene routiene <BR>-ret = 2. adresse (interruptrücksprung) vom stack -> PC <BR> <BR>sinn: <BR>interruptlogik freigeben um das runterzählen von timer1_ext24 sicherstellen auch wenn der durchlauf der eigenen routiene länger dauert als ein timerduchlauf. <BR>also nicht sinnlos sondern recht clever ;-) <BR> <BR>tschau MACE <BR>
Powered by vBulletin® Version 4.1.12 Copyright ©2012 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.