Hallo Leute, bin neu dabei, lerne gerade Assembler und habe, eine für Euch einfache, Frage: Habe eine Veriable mx definiert: .set mx = 0b00000000 Den Wert der Variabel möchte ich in einer Schleife incrementieren... Aber wie ? Wenn ich "inc mx" eingebe kommt ein Fehler dass das Register falsch währe... Ich benutze AVR-Studio im Simulationsmodus und PonyPro2000, habe ein Atmel Evaluationboard Vers. 2.0 von der Fa.Pollin und ein mega8 eingesetzt. Hat jemand eine einfache Erklärung für mich ? Vielen Dank PS: Lerne/lese gerade das AVR-Tutorial aber es fällt mir alles noch ein wenig schwer.... sollte ich was überlesen haben? Danke
Hi In Assembler gibt es keine Variablen. Alle Operationen werden mit Registern gemacht. z.B. ldi r16,0b00000000 inc r16 Mit '.def' kannst du Registern Namen zuweisen: .DEF ior=r16 Dann: ldi ior,0b00000000 inc ior MfG Spess
Hallo Spess53, vielen Dank für die schnelle Antwort. Habe es genau so gemacht wie Du es zeigst, mein Problem war dass die Software (die Demo für ADC im AVR-Tutorial)alle Register von r16 - r31 belegt hat so dass ich die Register von r1 -r15 benutzen muss. Dabei kam immerwieder der Fehler das es das falsche Register währe.... Deswegen meine Frage! Eigentlich will ich versuchen den Demo-Code von der AVR-Tutorial-Seite (ADC) zum laufen zu bringen, möchte aber jetzt dass nicht nur ein Kanal gelesen wird sondern alle 6(8) Kanäle des mega8 schön nacheinander. Kannst Du mir da weiterhelfen ? Vielen Dank
> .set mx = 0b00000000 definiert eine Konstante im Assembler, nicht im Programm. Deswegen kann man sie auch nicht mit einem Maschinenbefehl verändern, denn sie esistiert zur Laufzeit des Programmes nicht mehr. @Spess53: > In Assembler gibt es keine Variablen. Alle Operationen werden mit > Registern gemacht. Das stimmt in der Allgemeinheit nicht. Viele Maschinen können z.B. Worte im Speicher in-/decrementieren. Der Befehl enthält dann keine Registerreferenz; u.U. wird das Statusregister verändert.
Die Register 0-15 koennen den Inc befehl nicht, nur die Register 16-31. Schmeiss den ADC raus. Der kann eh nicht alle diese register dauernd belegen. Hin und wieder muessen Variablen deshlab im RAM lagern.
Hallo Uhu, danke für die schnelle Antwort. Was bedeutet das für mich ? Wie kann ich es dann schaffen dass ich die MUX-Variabel so umschalte dass alle ADCs der Reihe nach abgefragt werden. Es geht um den Code aus dem AVR-Tutorial (ADC). Mit diesem Code experimentiere ich rum... ; ADC initialisieren: Single Conversion, Vorteiler 128, ohne MUXx-Angaben wird Kanal 0 gesetzt. ldi temp1, (1<<REFS0) | mx; oder (m2<<MUX2) | (m1<<MUX1) | (m0<<MUX0) ;Kanal 0, interne Referenzspannung 5V (1<<MUX0)|(1<<MUX1)|(1<<MUX2) out ADMUX, temp1 ldi temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) ; Vorteiler = 128 out ADCSRA, temp1 Wie Du sehen kannst muss ich in der "temp1" diese Werte für die ADMUX eingeben um den Kanal auszuwählen..... Dachte mir aber ich nehme eine Variable (mx), belege sie mit einem Wert den ich dann in einer Schleife incrementiere. Manuell funktioniert es: ;MUXx-Werte als Variable beim initialisieren einsetzen. .equ m2 =1 ;Variable .equ m1 =0 .equ m0 =1 ;oder mit .set eine veränderbare Variable .set mx =0b00000101 ; ADC-Eingänge binär schalten, 0b00000000= ADC0, 0b00000001=ADC1 usw. => 0b00000101 = Kanal 6 Also wenn ich dies Variable manuell ändere dann wird auch ein anderer ADC-Kanal gelesen. Aber wie schaffe ich es das ganze in einer Schleife zu zwengen ? Vielen Dank
Robert Breicher wrote: > Hallo Spess53, > vielen Dank für die schnelle Antwort. > Habe es genau so gemacht wie Du es zeigst, mein Problem war dass die > Software (die Demo für ADC im AVR-Tutorial)alle Register von r16 - r31 > belegt hat so dass ich die Register von r1 -r15 benutzen muss. > Dabei kam immerwieder der Fehler das es das falsche Register währe.... > Deswegen meine Frage! Im AVR werden die Regsiter in 'die Oberen' und 'die Unteren' unterteilt. Der Unterschied, wie du selbst schon festgestellt hast, zwischen den beiden ist, dass mit den unteren Registern nicht alle Operationen möglich sind. Aber: Du kannst dir ja eines der oberen Register temporär freischaufeln. Du kannst es zb mit einem Push auf den Stack schieben, dann machst du deine Operationen mit dem Register und wenn du damit fertig bist, holst du dir den auf dem Stack zwischengespeicherten alten Registerinhalt mit einem Pop wieder zurück. Wahrscheinlicher ist es allerdings, das du mit einer Reorganisation deines Programmes genügend Register so freibekommst, dass du das alles gar nicht brauchst. Es ist selten, dass tatsächlich alle Register ständig gleichzeitig im Einsatz sind. Es spricht nichts dagegegen, ein Register für mehrere Aufgaben zu benutzen. Solange es zu keiner zeitlichen Überschniedung kommt, ist das ja auch kein Problem. > Eigentlich will ich versuchen den Demo-Code von der AVR-Tutorial-Seite > (ADC) zum laufen zu bringen, möchte aber jetzt dass nicht nur ein Kanal > gelesen wird sondern alle 6(8) Kanäle des mega8 schön nacheinander. > Kannst Du mir da weiterhelfen ? Wozu brauchst du da so viele Register? Du kannst die 6 Kanäle ja sowieso nicht alle gleichzeitig auslesen, sondern nur hintereinander. Und da du mit den Werten ja irgendetwas machen willst, bietet es sich ja geradezu an, dieselben Register reihum für die einzelnen Kanäle zu benutzen. Wenn du diese Woche etwas im Külschrank einlagern musst, heist das ja nicht, dass du dazu die Tupperdose von letzter Woche nicht benutzen kannst, wenn deren Inhalt schon längst aufgegessen wurde.
Hallo sechzweifuenf, danke für die schnelle Antwort, wie gesagt, ich bin ein Neuling, lerne gerade Assembler und den Umgang mit den Megaxxx. Kannst Du mir näher erläutern was Du genau meinst? Vielen Dank
Hallo Karl-Heinz, danke für Deine schnelle Antwort. Es hört sich sehr vernünftig an was Du sagst, da ich aber noch nicht die Routine habe um sowas zu machen, (seh den Wald vor lauter Bäume nicht) würde mir jetzt eine Demo sehr viel helfen.... (Ich kann nicht erkennen welche Register gerade nicht benutzt werden....!) Vielen Dank
> ; ADC initialisieren: Single Conversion, Vorteiler 128, ohne > MUXx-Angaben wird Kanal 0 gesetzt. > ldi temp1, (1<<REFS0) | mx; oder (m2<<MUX2) | (m1<<MUX1) | > (m0<<MUX0) ;Kanal 0, interne Referenzspannung 5V > (1<<MUX0)|(1<<MUX1)|(1<<MUX2) > out ADMUX, temp1 > ldi temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) ; > Vorteiler = 128 > out ADCSRA, temp1 > > Wie Du sehen kannst muss ich in der "temp1" diese Werte für die ADMUX > eingeben um den Kanal auszuwählen..... Schon. Aber danach brauchst du temp1 nicht mehr. Es wurde an dieser Stelle nur dafür benutzt um den Wert für das AMUX Register bzw. das ADCSRA Register zusammenzustellen. Sobald dieser Vorgang abgeschlossen ist, kannst du temp1 für irgendwelche anderen Dinge verwenden. Dachte mir aber ich nehme eine Variable (mx), belege sie mit einem Wert den ich dann in einer Schleife incrementiere. Manuell funktioniert es: > ;MUXx-Werte als Variable beim initialisieren einsetzen. > .equ m2 =1 ;Variable > .equ m1 =0 > .equ m0 =1 > ;oder mit .set eine veränderbare Variable > .set mx =0b00000101 ; ADC-Eingänge binär schalten, 0b00000000= ADC0, > 0b00000001=ADC1 usw. => 0b00000101 = Kanal 6 Das sind keine Variablen. Das sind Vereinbarungen mit dem Assembler, sodass er im weiteren Programmtext, wenn auch immer er den Text 'm2' sieht, er diesen Text 'm2' durch den Text '1' ersetzen soll. Das hat nichts mit Variablen zu tun, sondern dient einzig und alleine dem Programmierer, sodass er Zahlenwerten die im Programm auftauchen einen Namen geben kann um so besser den Überblick zu behalten, was an dieser Stelle überhaupt passieren soll. Wenn du beispielsweise irgendwo siehst (das ist jetzt kein Assmebler, sondern soll das Prinzip verdeutlichen) x = 0.19 * y dann weist du zunächst mal nicht, was diese Berechnung soll. Mache ich mir aber eine derartiges Defintion .equ Mehrwertsteuer = 0.19 x = Mehrwertsteuer * y dann erzählt mir hier der Programmtext schon sehr viel mehr. Es geht offensichltich um die Berechnung der Steuerhöhe bei einem vorgegebenem Betrag.
Robert Breicher wrote: > Hallo Karl-Heinz, > danke für Deine schnelle Antwort. > Es hört sich sehr vernünftig an was Du sagst, da ich aber noch nicht die > Routine habe um sowas zu machen, (seh den Wald vor lauter Bäume nicht) > würde mir jetzt eine Demo sehr viel helfen.... > (Ich kann nicht erkennen welche Register gerade nicht benutzt > werden....!) Das ist eines der Probleme im Assembler. Mach dir einen Ausdruck im Programm, schnapp dir ein paar Buntstifte und geh dein Programm durch, wo welches Register benutzt wird. Mit dem Buntstift kannst du dann neben dem Programmtext eine Linie ziehen, die dir angibt von wo bis wohin ein bestimmtes Register gebraucht wird. Ausserhalb dieses Bereichs kannst du dasselbe Register dann logischerweise für andere Dinge benutzen. Nehmen wir mal das ADC Beispiel aus dem Tutorial: Was ist mit dem Register temp5? Beim Label outp bekommt es zb einen Wert zugewiesen. Wenn du den Programmtext weiter nach unten durchgehst, stellst du fest, dass es diesen Wert bis zu der Stelle subi adlow,-'0' ;an UART Senden mov temp1, temp5 ; Zehntausender Stelle rcall transmit behalten muss. Damit hast du die Lebensspanne des Registers festgelegt: Von wo bis wohin darfst du das Register nicht verändern. Aber ausserhalb dieses Bereichs kannst du dieses Register für ganz andere Dinge verwenden. Natürlich unter der Voraussetzung, dass sich die 'Lebensspannen' dieser Bereiche nicht überlappen. Das wird ja auch im Demoprogramm gemacht. Für temp5 gibt es einen zweiten Bereich. Es wird im Abschnitt Main: clr temp1 clr temp2 clr temp3 clr temp4 ldi temp5, 0 ; 256 Schleifendurchläufe ; neuen ADC-Wert lesen (Schleife - 256 mal) sample_adc: sbi ADCSRA, ADSC ; den ADC starten wait_adc: sbic ADCSRA, ADSC ; wenn der ADC fertig ist, wird dieses Bit gelöscht rjmp wait_adc ; ADC einlesen: in adlow, ADCL ; immer zuerst LOW Byte lesen in adhigh, ADCH ; danach das mittlerweile gesperrte High Byte ; alle 256 ADC-Werte addieren add temp2, adlow ; addieren adc temp3, adhigh ; addieren über Carry adc temp4, temp1 ; addieren über Carry, temp1 enthält 0 dec temp5 ; Schleifenzähler MINUS 1 brne sample_adc ; wenn noch ebenfalls verwendet. Dort, beim Kommentar ' 256 Schleifendurchläufe' bekommt es den Wert 0 und ziemlich weit unten in diesem Abschnitt wird es mal decrementiert. Das ist also der zweite Lebensbereich für dieses Register. Er kollidiert nicht mit dem andern Abschnitt und daher ist das auch in Ordnung.
Hallo Karl-Heinz, danke noch mal... Also wenn ich es richtig verstanden habe kann ich "temp1" nach dem der Wert für den ADMUX gesetzt wurde wieder mit anderen "Aufgaben" belegen. Im Abschnitt "Main" wird "temp1" mit clr ja freigemacht, danach kann er wie Du meinst auch wieder für andere Zwecke benutzt werden. Noch einen Tipp ? Danke
Im übrigen: Im ADC Tutorial sind noch jede Menge Register frei. Du brauchst nur ein einziges neues Register, welches den als nächstes auszulesenden Kanal enthält. Warum nimmst du nicht Register r26 dafür her?
Hi Deinen aktuellen Kanal brauchst du nicht in einem Register speichern, denn der steht in ADMUX. Meine Variante (ohne 'temp'-Quatsch): in r16,ADMUX mov r17,r16 inc r16 ; Kanal incrementieren andi r16,0b00000111 ; Kanalnummer 0..7 andi r17,0b11111000 ; restliche Bits or r16,r17 out ADMUX,r16 für 6 kanäle .... andi r16,0b00000111 ; Kanalnummer cpi r16,6 brne abc clr r16 abc: andi r17,0b11111000 .... Wenn die benutzten Register belegt sind, dann mit push/pop sichern. MfG Spess
Danke Karl-Heinz, jetzt verstehe ich was Du meinst, jetzt wird es etwas heller :-) Muss ich das Register zuerst mit "clr" löschen um es benutzen zu können? Danke
Karl heinz Buchegger wrote: > Im übrigen: > Im ADC Tutorial sind noch jede Menge Register frei. > Du brauchst nur ein einziges neues Register, welches > den als nächstes auszulesenden Kanal enthält. > Warum nimmst du nicht Register r26 dafür her? Hallo Karl-Heinz, hatte den selben Fehler mit r26 - r31.... Dachte mir es werden für "wörter" benutzt..... Gruß
Es gibt konstaten : .equ default =4; Es gibt benamste register .def ErrorCode = r15; .def Temp = r16; .def U1 = r17; .def U2 = r18; Es gibt benamste variablen .DSEG ; im datensegment .mystate: .byte 1; 1 byte fuer mystate .ADCChannel: .byte 1; ADC Channel .ADC1: .byte 2; ADC1 word .ADC2: .byte 2; ADC2 .ADC3: .byte 2; ADC3 .ADC4: .byte 2; ADC4 .ADC5: .byte 2; ADC5 .ADC6: .byte 2; ADC6 .ADC7: .byte 2; ADC7 .ADC8: .byte 2; ADC8 .RxBuf: .byte 64; Rxbuffer 64 byte Lade von Variablen ins register SetYPtr Mystate ld temp,Y zurueckschreiben st Y,temp Wobei SetYPtr ein Makro ist... Siehe auch : http://www.ibrtses.com/embedded/avrmacros.html http://www.ibrtses.com/embedded/avrsmallstuff.html
Hallo Spess53, danke für den Demo-Code, werde es gleich versuchen.... Muss nur gucken wo genau welcher Abschnitt eingebaut werden soll.... Nicht so einfach für mich...... Vielen Dank
Robert Breicher wrote: > Danke Karl-Heinz, > jetzt verstehe ich was Du meinst, jetzt wird es etwas heller :-) > Muss ich das Register zuerst mit "clr" löschen um es benutzen zu können? Nein. Ein Register behält seinen Wert, bis du einen anderen Wert hineinschreibst. Wenn du haben möchtest, dass das Register einen neuen Wert von 0 enthält, dann muss man auch 0 hineinschreiben. Der 'clr' macht das.
Hallo rene, vielen Dank für die schnelle Antwort, Werde die Links besuchen und weiter studieren.... Danke für die klasse Übersicht und Info... Gruß
Danke Karl-Heinz, kappiert :-) Also einfach mit einem neuen Wert überschreiben..... OK. Danke
spess53 wrote: > Hi > > Deinen aktuellen Kanal brauchst du nicht in einem Register speichern, > denn der steht in ADMUX. > > Meine Variante (ohne 'temp'-Quatsch): > > in r16,ADMUX > mov r17,r16 > inc r16 ; Kanal incrementieren > andi r16,0b00000111 ; Kanalnummer 0..7 > andi r17,0b11111000 ; restliche Bits > or r16,r17 > out ADMUX,r16 > > für 6 kanäle > .... > andi r16,0b00000111 ; Kanalnummer > cpi r16,6 > brne abc > clr r16 > abc: andi r17,0b11111000 > .... > > Wenn die benutzten Register belegt sind, dann mit push/pop sichern. > > MfG Spess Hallo Spess, kannst Du mir die Logik Deines Codes erklären? Ich möchte gerne verstehen wie man denken muss um sowas lösen zu können. Es ist ja sowas wie ein Algorithmuss, oder ? Ich möchte nur gerne verstehen was ich da mache, nicht nur einfach "copy & past".. Vielen Dank
Robert Breicher wrote: > spess53 wrote: >> Hi >> >> Deinen aktuellen Kanal brauchst du nicht in einem Register speichern, >> denn der steht in ADMUX. >> >> Meine Variante (ohne 'temp'-Quatsch): >> >> in r16,ADMUX >> mov r17,r16 >> inc r16 ; Kanal incrementieren >> andi r16,0b00000111 ; Kanalnummer 0..7 >> andi r17,0b11111000 ; restliche Bits >> or r16,r17 >> out ADMUX,r16 >> >> für 6 kanäle >> .... >> andi r16,0b00000111 ; Kanalnummer >> cpi r16,6 >> brne abc >> clr r16 >> abc: andi r17,0b11111000 >> .... >> >> Wenn die benutzten Register belegt sind, dann mit push/pop sichern. >> >> MfG Spess > > Hallo Spess, > kannst Du mir die Logik Deines Codes erklären? > Ich möchte gerne verstehen wie man denken muss um sowas lösen zu können. > Es ist ja sowas wie ein Algorithmuss, oder ? > Ich möchte nur gerne verstehen was ich da mache, nicht nur einfach "copy > & past".. Geh davon aus, dass die Kanalnummer um 1 erhöht werden muss. Das ist dein Ansatzpunkt. UNd jetzt geh den Code Instruktion für Instruktion durch und versuch nachzuvollziehen was da passiert. Immer mit dem Hintergedanken: die Kanalnummer muss um 1 erhöht werden und die Kanalnummer steht im ADMUX Register. Und innerhalb dieses Registers sind es nur die untersten 3 Bits, die die Kanalnummer enthalten. > Vielen Dank
Hi ADMUX hat folgende Belegung: Bit 7 6 5 4 3 2 1 0 REFS1 REFS0 ADLAR – MUX3 MUX2 MUX1 MUX0 in r16,ADMUX ; ADMUX nach r16 mov r17,r16 ; Kopie nach r17,für REFS1,REFS0,ADLAR inc r16 ; r16=r16+1 andi r16,0b00000111 ; Bit 7..3 werden ausgeblendet, r16= MUX2..MUX0 ; Kanal 0..7 andi r17,0b11111000 ; Bit 2..0 werden ausgeblendet, r17=REFS1,REFS0,ADLAR or r16,r17 ; Wert für ADMUX wieder zusammensetzen out ADMUX,r16 ; neuer Wert nach ADMUX Bei 6 Kanälen cpi r16,6 ; Kanalnummer>5 brne abc ; wenn<>6 nach abc springen clr r16 ; Kanalnummer auf 0 setzten abc: ... ; weiter im Programm MfG Spess
Halloo Spess, vielen Dank für Deine Hilfe, total willkommen ! Verstehe von Minute zu Minute mehr.... Bin gerade dabei Deinen Code in der Demo anzupassen, habe aber noch das Problem mit r16/r17, die muss ich irgendwie mit pop/push bearbeiten denn der Code funktioniert nicht einfach so nach dem ich ihn eingefügt habe.... Also muss ich etwas graue Zellen bemühen...... Vielen Dank PS: Einen Hinweiss wie man sowas am besten macht ? Gruß
Hi Bedanke dich für deine Schwierigkeiten erst mal bei denen, die diesen 'tempXYZ'-Unsinn eingeführt haben. Da ich dein Programm nicht kenne, kann ich nur mutmaßen. Irgendwo steht da: in xxx,ADCL in yyy,ADCH danach wird mit xxx,yyy irgendwas gemacht. Und danach wäre die Stelle um den Kanal umzuschalten. Als nächstes springst du wieder an die Stelle , an der die ADC-Conversation gestartet wird. Dann beginnt das spiel von vorn. MfG Spess
spess53 wrote: > > Da ich dein Programm nicht kenne, kann ich nur mutmaßen. > > MfG Spess Hallo Spess, es handelt sich um die Demo in dem AVR-Tutorial (ADC) auf diesen Seiten. Ich kämpfe gerade mit dem Code, er gibt jetzt nur 1023 aus, egal welchen Kanal ich jetzt eingebe.... Zumindest kann ich jetzt in der Software "Terminal" nur eine Zahlenreihe mit 01023 sehen.... Bedanke mich für Deine Hilfe... Eine Idee wie ich dein Code da anpassen könnte? Ich will jeden Kanal einlesen, also muss ich den ADMUX in einer Schleife haben....oder ? Habe Deinen Code eingefügt und versuche gerade daraus schlau zu werden. Gruß
Der ADC will den Kanal gewaehlt haben, dann startet man eine Wandlung. Wenn die Wandlung fertig ist, liest man aus. Und setzt den neuen Kanal. usw. Zuerst sollte ein Kanal vernuenftige Werte liefern bevor ich mich ums Umschalten kuemmern wuerde.
spess53 wrote: > Hi > > > ADMUX hat folgende Belegung: > Bit 7 6 5 4 3 2 1 0 > REFS1 REFS0 ADLAR – MUX3 MUX2 MUX1 MUX0 > > > in r16,ADMUX ; ADMUX nach r16 > mov r17,r16 ; Kopie nach r17,für REFS1,REFS0,ADLAR > inc r16 ; r16=r16+1 > andi r16,0b00000111 ; Bit 7..3 werden ausgeblendet, r16= MUX2..MUX0 > ; Kanal 0..7 > andi r17,0b11111000 ; Bit 2..0 werden ausgeblendet, > r17=REFS1,REFS0,ADLAR > or r16,r17 ; Wert für ADMUX wieder zusammensetzen > out ADMUX,r16 ; neuer Wert nach ADMUX > Hi Spess, habe eine Frage zu Deinem Code: Warum incrementierst Du da r16 ? Also: Du lädst (in) ADMUX nach r16 dann kopierst r16 nach r17 dann inc r16 ... aber warum ? andi r16 und andi r17 sind klar or r16, r17 auch soweit klar wobei r17 anders sein muss da ich RFS0=1 benötige. Alles andere soweit klar.... Gruß & danke
Robert Breicher wrote: > habe eine Frage zu Deinem Code: > Warum incrementierst Du da r16 ? > Also: > Du lädst (in) ADMUX nach r16 > dann > kopierst r16 nach r17 > dann inc r16 ... aber warum ? Na ja. Du willst doch die um 1 höhere Kanalnummer haben
rene wrote: > Zuerst sollte ein Kanal vernuenftige Werte liefern bevor ich mich > ums Umschalten kuemmern wuerde. Hallo Rene, also der Demo-Code (AVR-Tutorial - ADC) hat bei mir funktioniert, jetzt kämpfe ich mit dem Code von Spess, da ich aber am lernen bin sind alle Schritte für mich noch sehr schwer/unklar, weiss z.B. nicht genau wie ich debn Code implementieren/anpassen muss, versuche jeden Befehl nachzuschlagen und zu kappieren, dann versuche ichdie Logik zu verstehen. Mühsam geht es weiter.... Danke Dir
Hi Karl-Heinz, ist soweit klar, aber ich will erst mal gucken dass ich einen Kanal wieder (mit Deinem Code) richtig lesen kann. Das macht mir noch Stress... Dann geht es ans incrementieren :-) Danke Dir
Hi Ich habe dir das Programm mal für deine Zwecke zurechtgestutzt.Ohne Gewähr. Ständiger Wert 1023 deutet auf Uin>Uref. MfG Spess
Hallo Spess, vielen dank für Deinen neuen Code. Habe ihn eingelesen und gestartet und wie gehabt kommen 2 Warnungen für r26 und r27: ...\thermo2\thermo2.asm(13): warning: Register r26 already defined by the .DEF directive Eine Idee ? Danke nochmals !
Robert Breicher wrote: > Hallo Spess, > vielen dank für Deinen neuen Code. > Habe ihn eingelesen und gestartet und wie gehabt kommen 2 Warnungen für > r26 und r27: > > ...\thermo2\thermo2.asm(13): warning: Register r26 already defined by > the .DEF directive Die kannst du fürs erste ignorieren.
spess53 wrote: > > Ständiger Wert 1023 deutet auf Uin>Uref. > > MfG Spess Hi Spess, ich habe ein Poti von ARef des Mega8 an GND, der Schleifer ist am ADC0 dran. Mit der Demo funktioniert es gut, habe keine Probs damit. Wenn ich am Poti drehe dann kann ich den Eingang (ADC0) auf GND legen, dann müsste 0000 ausgegeben werden.... tut er aber nicht, das bedeutet dass der Eingang nicht richtig funktioniert oder konfiguriert ist..... oder ? Gruß
Hi Schon mal direkt am Pin gemessen? MfG Spess
Karl heinz Buchegger wrote: > > Die kannst du fürs erste ignorieren. Hi Karl-Heinz, Warnungen ignorieren ? Geht das einfachso ? Danke PS: Habe den Code jetzt in den Mega8 übertragen, der funktioniert wirklich super, sau schnell... Habe nur jetzt ein Problem: Mein Mega ist mit einem externen 16MHz-Quartz bestückt und die Fuse eingestellt, jetzt kann ich nicht mehr lesen wenn ich den Code so anpasse. Es kommen komische Zeichen raus.... Mit meiner alten Version konnte ich mit 9600 Boud sauebr lesen.. Gibt es eine Möglichkeit nach dem alle 6 Kanäle einmal gelesen wurden dass eine leere Zeile ausgegeben wird ?
Robert Breicher wrote: > Karl heinz Buchegger wrote: > >> >> Die kannst du fürs erste ignorieren. > > Hi Karl-Heinz, > Warnungen ignorieren ? > Geht das einfachso ? In dem Fall ist das ok. Die Warnung bezieht sich darauf, dass es eine zweite .def Anweisung gibt (die im Include File steckt), die diesem Register bereits einen Namen gegeben hat. Es handelt sich um das Registerpärchen r26 und r27, das gemeinsam als das X-Register bekannt ist. Da du aber keine Operationen mit dem X-Register machst, spielt es keine Rolle, dass du r26 für andere Zwecke benutzt. > PS: > Habe den Code jetzt in den Mega8 übertragen, der funktioniert wirklich > super, sau schnell... > Habe nur jetzt ein Problem: > Mein Mega ist mit einem externen 16MHz-Quartz bestückt und die Fuse > eingestellt, jetzt kann ich nicht mehr lesen wenn ich den Code so > anpasse. Es kommen komische Zeichen raus.... Hast du auch nicht vergessen, die Frequenzangabe im Code anzupassen. Wenn du das nicht gemacht hast, dann werden die UART Initialisierwerte falsch berechnet. > Gibt es eine Möglichkeit nach dem alle 6 Kanäle einmal gelesen wurden > dass eine leere Zeile ausgegeben wird ? Sicher. Nach der 6.ten Ausgabe gibst du nochmal ein CR/LF aus. Im Originalcode sind das die Ausgaben von 10 und 13. Die beiden sorgen dafür, dass eine neue Zeile angefangen wird.
Hallo Stefan, danke für die schnelle Antwort. Schon komisch..... Danke
Karl heinz Buchegger wrote: > Robert Breicher wrote: >> Karl heinz Buchegger wrote: > Hast du auch nicht vergessen, die Frequenzangabe im Code > anzupassen. Wenn du das nicht gemacht hast, dann werden die > UART Initialisierwerte falsch berechnet. > >> Gibt es eine Möglichkeit nach dem alle 6 Kanäle einmal gelesen wurden >> dass eine leere Zeile ausgegeben wird ? > > Sicher. > Nach der 6.ten Ausgabe gibst du nochmal ein CR/LF aus. > Im Originalcode sind das die Ausgaben von 10 und 13. Die > beiden sorgen dafür, dass eine neue Zeile angefangen wird. Hi, nein, habe es gleich gemacht. Habe auch das Problem dass meine Software (Terminal) nicht immer sauber lesen kann, ich muss sie öfters diconnesten/reconnecten um den Wert lesen zu können, dazwischen gibt es Hyroglifen aus.... Das macht er jetzt auch bei einer Boudrate von 14400 ! Gibt es da ein Problem was ich anders lösen muss ? danke
Robert Breicher wrote: > > Hi, > nein, habe es gleich gemacht. > Habe auch das Problem dass meine Software (Terminal) nicht immer sauber > lesen kann, ich muss sie öfters diconnesten/reconnecten um den Wert > lesen zu können, dazwischen gibt es Hyroglifen aus.... > Das macht er jetzt auch bei einer Boudrate von 14400 ! > > Gibt es da ein Problem was ich anders lösen muss ? Eigentlich nicht. Wenn die Taktfrquenz stimmt, die Baudrate stimmt, dann solltest du im HT was sehen. Nur zur Sicherheit: Die Übertragung hat schon funktioniert? Du hast nur das neue Programm eingespielt und auch an den Fusebits nichts verändert?
Hallo Karl-Heinz, also die Übertragung hat geklappt, die Fuse-Bits hatte ich schon am Anfang angepasst, teste die ganze Sache schon mit dem schnelle Quartz. Habe nur Deinen Code eingespielt, vorher nur noch den Tackt und Boud angepasst... Es funzt auch, aber wenn ich die Software starte kommt gelegentlich Kauderwelsch raus, dann connecte und disconnecte ich einige Male, dann klappt es wieder.... Also etwas instabil... Eine Idee ? Gruß & Danke
Robert Breicher wrote: > Hallo Karl-Heinz, > also die Übertragung hat geklappt, die Fuse-Bits hatte ich schon am > Anfang angepasst, teste die ganze Sache schon mit dem schnelle Quartz. > Habe nur Deinen Code eingespielt, vorher nur noch den Tackt und Boud > angepasst... > Es funzt auch, aber wenn ich die Software starte kommt gelegentlich > Kauderwelsch raus, dann connecte und disconnecte ich einige Male, dann > klappt es wieder.... > Also etwas instabil... > Eine Idee ? Nicht wirklich. Du solltest nur darauf achten, dass der Empfänger empfangsbereit ist, bevor der Sender loslegt. Dies deshalb damit der Empfänger auch sauber auf das erste Byte synchronisieren kann. Aber wenn bei dir Hyperterminal sowieso ständig durchläuft, sollte das eigentlich kein Problem sein.
Hallo Karl-Heinz, danke erstmal für Deine Hilfe. Habe den Code eingegeben, er funzt in soweit dass er den Wert sauber ausgibt, das Problem mit gelegentlichen Sonderzeichen liegt möglicherwiese an der Anpassung meiner seriellen Schnittstelle. Das werde ich noch lösen. Habe da eine andere Frage: In der Demo (von der Tutorial-Seite) werden die 256 Messungen nochmal bearbeitet um den Mittelwert zu errechnen und erst den dann an die UART gesendet. Gibt es einen Grund warum Du diesen Teil einfach entfernt hast? Zur Zeit werden die Änderungen am Poti erst nach einer Weile angezeigt, ich denke es sind die 256 Steps die gelesen werden und wenn die Schleife zu ende ist wird der neue Wert ausgegeben.... Kann ich den einfach wieder einfügen ? Habe den Code eingefügt und Übertragen, jetzt wird etwas ausgegeben aber ich kann es mit nichts in Verbindung bringen.... Es hat nichts mit dem Poti zu tun..... Danke
Robert Breicher wrote: > (Ich kann nicht erkennen welche Register gerade nicht benutzt > werden....!) Das Problem ist alt, aber lösbar. Du mußt Dich erstmal hinsetzen und einige Regeln aufschreiben: 1. Reserviere einige Register (6..16) als Scratchpad. Diese Register kann jede Funktion (Unterprogramm) nach belieben benutzen. D.h. derjenige, der eine Funktion aufruft, geht davon aus, daß nach dem Return diese Register nicht mehr ihren alten Wert beinhalten. Werden aber Werte noch gebraucht, muß der Aufrufer sie Pushen oder im SRAM abspeichern. R0, R1 sind automatisch Scratchpadregister, da sie von Operationen (LPM, MUL) verändert werden. Benötigt eine Funktion mehr als die Scratchpadregister, muß es diese pushen und popen. Sie kann allerdings davon ausgehen, daß sie selber Unterfunktionen aufrufen kann und diese dann erhalten bleiben. 2. Lege Dir Aufrufkonventionen fest, in welchen Registern Funktionen Argumente geliefert bekommen, bzw. sie Returnwerte zurückliefern. Es reichen in der Regel bis zu 3 16Bit Argumente (6 Register) oder 2 32Bit Argumente (8 Register) aus. Vorzugsweise nimmt man dazu welche von den Scratchpadregistern. 3. Reseviere Scratchpadregister (5..10) für Interrupts. Damit muß man nicht aufwendig pushen und popen, sondern kann gleich loslegen. Da sich Interrupts nicht gegenseitig unterbrechen können, kann die jeder Interrupt benutzen. Da man 3 Pointer hat, nehme ich immer einen (X) mit für die Interrupts. Das Main benutzt dann nur Y und Z. 4. Alle anderen Variablen legt man im SRAM an. Häufig benutzte Variablen können auch die restlichen Register benutzen. Aber Register, die als Variablen verwendet werden, dürfen nicht mehrfach verwendet werden! 5. Oftmals wird auch ein Null-Register reverviert, um schnell mit 0 zu rechnen. Oder sogar 2, um mit MOVW schnell einen 16Bit-Wert zu nullen. z.B. R2, R3. 6. Den so festgelegten Registern gibt man mit .def dann aussagekräftige Namen. Man verwendet nie direkt Register, außer R0,R1. Peter
Hallo Peter, vielen Dank für Deine Hilfe, jetzt kommt Plan in der ganzen Sache. Vielen Dank. PS: Muss in Ruhe alles verdauen was Du mir jetzt vorgelegt hast.... Kämpfe noch mit dem Code von Spess53.... Da gibt es einen Zähler der Schleifen - 256 - aber ich weiss noch nicht wie es funktioniert.... Ich bearbeite den Demo-Code aus dem AVR-Tutorial (ADC) und einige Leute haben mir da viel geholfen. Spess53 hat mir was zusammengebaut anhand diesen Demo-Codes, hat aber den Teil für das Errechnen des Mittelwertes rausgenommen und ich versuche heraus zu finden warum und wie ich es wieder einbauen kann..... Gruß
Hi Von dem Schleifenzähler ist nur noch der Kommentar drin. Mir ging es eigentlich darum, dir die Kanalumschaltung zu verdeutlichen. Deshalb habe ich die Mittelwertbildung rausgelassen. Du brauchst eigentlich nur die Teile aus dem Originalcode wieder reinkopieren. MfG Spess
Hi Spess, vielen Dank noch mal. Es wurde mir irgendwann klar dass Du es für mich einfacher machen wolltest, hat mich am Anfang etwas irritiert :-) Hatte es wieder drin aber es funzte nicht, es kamen Zahlen raus die aber nicht mit meinem Poti was zu tun hatte.... Jetzt ist es wieder draussen, habe dafür die Ausgabe insofern verändert dass ich jede Zählung mit Tabs trenne und nach dem alle 6 Kanäle durch sind kommt eine neue Zeile.... Bin mächtig stolz :-) Werde mich jetzt an der Mittelwertberechnung machen.....grübbel... Warum werden nach der Rechnerei falsche/andere Werte ausgegeben... Es hat mit der neuen Registerbelegung zu tun...denke ich! Danke Dir für die enorme Hilfe ! Gruß
Hallo an alle, vielen Dank für euere Hilfe.... Es ist unglaublich hilfreich was Ihr da zustande bringt. Vielen Dank und eine gute Nacht PS: Für heute ist Ende, morgen in alles Frische geht es weiter.... Danke an alle Ciao
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.