> sts sreg,R24 '... und zurückschreiben
auf welchem Controller programmierst du denn???
Mit einem Mega8 funzt das sicher nicht!
Wenn du noch Register frei hast, geht es schneller mit mov als mit
sts/lds zu laden und zu speichern.
julian
In der oben angegebenen Form läuft das auf einem Atmega8.
Wird später auf einen Mega32 übertragen.
Wie kann ich deinen Hinweis umsetzen ? STS benötigt doch nur einen Takt.
W.
Hi
>Kann man nachfolgenden Code noch verbessern?
Etwas. Wenn das Ergebnis 0 wird sind dein Speicherstellen $FFFF. Da
brauchst du nichts wieder zurückrechnen unbd speichern.
Danke für den Hinweis. Aber $FFFF kommt nur im Notfall vor.
Hab gerade noch einen anderen Gedanken. Das High-Byte muss ja nur nach
256 Schritten erhöht werden. Dann werde ich wohl ADIW raus nehmen.
W.
Wolfgang Schmidt schrieb:> In der oben angegebenen Form läuft das auf einem Atmega8.
Dann musst du das SReg mit in/out sichern! out kann bis 3F=63
adressieren,
Das SREG hat die Adresse 3Fh = 63
> Wird später auf einen Mega32 übertragen.
Wieso schreibst du nicht gleich auf einem Mega32
> Wie kann ich deinen Hinweis umsetzen ? STS benötigt doch nur einen Takt.
Falsch! sts/lds braucht immer 2 Takte, mov einen!!!
julian
PS: Datenblatt und AVR-Studio ASM-Help hilft gerne!
Hi
>Hab gerade noch einen anderen Gedanken. Das High-Byte muss ja nur nach>256 Schritten erhöht werden. Dann werde ich wohl ADIW raus nehmen.
Einfacher wird es dadurch auch nicht. Wenn andere Werte vorkommen können
bleib bei deiner Variante.
MfG Spess
@Julian
MOV geht nur zwischen Registern. Meine IRQ-Routine wird über einen Timer
aufgerufen. Somit werden die anderen Register vom Hauptprogramm in einer
Hochsprache benötigt. Um STS komme ich nicht herum.
Hab den Code mal umgeschrieben:
.equ Count0_l = $60
.equ Count0_h = $61
.equ Count1_l = $62
.equ Count1_h = $63
push R24 'Register retten
lds r24,sreg 'Statusregister einlesen und
push r24 'auf den Stack schieben
lds R24,Count0_l '$60 = Low byte erhöhen
inc R24
sts Count0_l,R24 'zurück schreiben
BRNE C0 'noch kein Überlauf
lds R24,Count0_h 'High byte erhöhen
inc R24
BREQ C0 'Überlauf festgestellt
sts Count0_h,R24 'zurück schreiben
C0:
lds R24,Count1_l '$60 = Low byte erhöhen
inc R24
sts Count1_l,R24 'zurück schreiben
BRNE C1 'noch kein Überlauf
lds R24,Count1_h 'High byte erhöhen
inc R24
BREQ C1 'Überlauf festgestellt
sts Count1_h,R24 'zurück schreiben
C1:
'Register und
Pop R24 'Statusregister zurückholen
sts sreg,R24 '... und zurückschreiben
pop R24
Ist noch nicht getestet.
Das Maximum wird jetzt erreicht, wenn das High-Byte $FF ist. Das genügt
mir auch.
W.
Wolfgang Schmidt schrieb:> @Julian>> MOV geht nur zwischen Registern. Meine IRQ-Routine wird über einen Timer> aufgerufen. Somit werden die anderen Register vom Hauptprogramm in einer> Hochsprache benötigt. Um STS komme ich nicht herum.
OK, ich dachte du programmierst nur in ASM
Jedoch solltest du dir das mit LDS r24, sreg nochmal anschauen:
Im Mega8/32 Datenblatt ist geschrieben, dass in/out noch auf das SREG
greifen können, und wenn du lds/sts verwendest, brauchst du 2 Takte
länger!
also:
push r24
in r24, SREG
push r24
und:
pop r24
out r24, SREG
pop r24
julian
HI
>Im Mega8/32 Datenblatt ist geschrieben, dass in/out noch auf das SREG>greifen können, und wenn du lds/sts verwendest, brauchst du 2 Takte>länger!
Tragischer ist aber, das er mit lds/sts SREG nicht auf SREG zugreift.
MfG Spess
Julian R. schrieb:> Jedoch solltest du dir das mit LDS r24, sreg nochmal anschauen:> Im Mega8/32 Datenblatt ist geschrieben, dass in/out noch auf das SREG> greifen können, und wenn du lds/sts verwendest, brauchst du 2 Takte> länger!
Nicht nur das, Du sicherst nicht das SREG, sondern was völlig anderes
(EEARH).
Peter
Mit SREG habe ich mal die Erfahrungen gemacht, dass eben diese Daten
häufig verloren gingen, wenn ich in eine ISR gesprungen bin.
Damals habe ich LDS/STS SREG benutzt und keine Probleme mehr gehabt.
Aber ich werde IN/OUT mal ausprobieren.
DAnke
W.
Wenn man GCC als Assembler nutzt, könnte es mit LDS/STS SREG
funktionieren. Da wäre dann aber IN R24, _SFR_IO_ADDR(SREG) die bessere
Lösung.
Beim Atmel Assembler sollte es aber richtig mit IN/OUT SREG sein.
Es lies mir keine Ruhe.
Ich habe mal meinen Code durch den Simulator gejagt und die Status-Bits
vor dem Sichern beliebig gesetzt. Mit LDS wird das Byte in das Register
R16 übertragen und auch nach dem Durchlauf und der Änerung einzelner
Bits genau so wieder mit STS hergestellt.
Habs auch mit IN/OUT probiert. ==> gleiches Ergebnis.
W.
Hi
>Mit SREG habe ich mal die Erfahrungen gemacht, dass eben diese Daten>häufig verloren gingen, wenn ich in eine IRQ gesprungen bin.>Damals habe ich LDS/STS SREG benutzt und keine Probleme mehr gehabt.>Aber ich werde IN/OUT mal ausprobieren.
Kann ich nicht so richtig glauben.
SREG repräsentiert bei allen AVRs den Wert $3F. Das ist die IO-Adresse,
die von in/out verwendet wird. Um auf die gleiche Adresse mit lds/sts
zugreifen zu können muss $5F (SREG+$20) verwendet werden.
MfG Spess
Hi
>Habs auch mit IN/OUT probiert. ==> gleiches Ergebnis.
Mach das mal im AVR-Studio oder mit einem ICE. Da wirst du sehen, das
das nicht so ist.
MfG Spess
Ich habe eine Bildschirmkopie beigelegt. Die StatusFlags sieht man oben
links. Diese ergeben $55 (hex) und dieser Wert ist auch auf der rechten
Seite im Register R16 zu sehen. Nach POP ... und STS wurden die
StatusFlags genau so wieder hergestellt.
Schickt den Code doch mal durch euren Simulator.
Bin gespannt.
Ich habe auch beide hex-Dateien durch einen Disassembler gejagt und
erhielt bei der Disassemblierung jeweils STS/LDS bzw IN/OUT. Also hat
mein Assembler auch den zugehörigen Code erzeugt.
W.
Warum sagst Du nicht gleich, daß Du Bascom Assembler benutzt !!!
Da kenne ich mich nicht aus, was der verzapft.
Und warscheinlich die anderen hier auch nicht.
Peter
Peter Dannegger schrieb:> Da kenne ich mich nicht aus, was der verzapft.
Durchaus logisches.
> Und warscheinlich die anderen hier auch nicht.
Nicht ganz.
Der Bascom Assembler weis daß er bei IN/OUT auf SREG mit &h3F zugreifen
muss und bei LDS/STS mit &h5F.
Funktion ist damit völlig korrekt, nur ineffektiv da IN/OUT 1 Takt
schneller ist und niemand ohne Notwendigkeit die langsamere Version
benutzt.
Hi
>Der Bascom Assembler weis daß er bei IN/OUT auf SREG mit &h3F zugreifen>muss und bei LDS/STS mit &h5F.>Funktion ist damit völlig korrekt, nur ineffektiv da IN/OUT 1 Takt>schneller ist und niemand ohne Notwendigkeit die langsamere Version>benutzt.
Bringt aber, wie hier gesehen, Probleme im richtigen Leben.
Zumindest steht es in der BASCOM-Hilfe richtig drin.
MfG Spess
spess53 schrieb:> Bringt aber, wie hier gesehen, Probleme im richtigen Leben.
Eigentlich nur, weil der TE die Helfer mit dem Verschweigen der
Programmiersprache in's Blaue geschickt hat.
Im Datenblatt des Atmega8 steht:
The I/O Memory can be accessed directly, or as the Data Space locations
following those of the Register File, 0x20 - 0x5F.
Also gibt es grundsätzlich zwei Möglichkeiten, IN/OUT und LDS/STS. Das
sollte jeder Assembler können.
Ich benutze MikoPascal und BASCOM. Beide Compiler haben beide Varianten
verarbeitet.
Es sind demzufolge gleichwertig:
LDS r16,SREG
LDS r16,$5F
IN r16,SREG
IN r16,$3F
Gleiches mit STS und OUT.
Ich wollte den Code bez. der Laufzeit optimieren.
W.
Hi
Du hast weiter oben geschrieben:
>Ich habe auch beide hex-Dateien durch einen Disassembler gejagt und>erhielt bei der Disassemblierung jeweils STS/LDS bzw IN/OUT. Also hat>mein Assembler auch den zugehörigen Code erzeugt.
Dabei hast du allerdings verschwiegen, das im disassemblierten Code eben
nicht auf die gleiche Adresse zugegriffen wird.
MfG Spess
Wolfgang Schmidt schrieb:> Also gibt es grundsätzlich zwei Möglichkeiten, IN/OUT und LDS/STS. Das> Sollte jeder Assembler können.
Aber nicht jeder Assembler muss Dir zwingend die Symbole dafür
bereitstellen. In den Includes zu AVR-Studio Assembler gibt's nur eine
Definition zu SREG und die ist 0x3f.
Da wird aus:
1
ldi r16, SREG
dann:
1
LDI R16,0x3F
Damit landest Du auf irgend einem anderen Register und deswegen waren
die Hinweise berechtigt.
Außerdem kompiliert Dein Code sowieso nicht unter Bascom, denn das hier:
1
adiw R24:R25,1
würde eine Fehlermeldung erzeugen.
> Ich wollte den Code bez. der Laufzeit optimieren.
Dann weist Du jetzt, daß IN/OUT schneller ist.
MWS schrieb:> Außerdem kompiliert Dein Code sowieso nicht unter Bascom,> denn das hier:adiw R24:R25,1> würde eine Fehlermeldung erzeugen.
Dann muss mein BASCOM ein anderes sein, denn ADIW ist im DAtenblatt des
Atmega8 zu finden !
W.
Hi
>Dann muss mein BASCOM ein anderes sein, denn ADIW ist im DAtenblatt des>Atmega8 zu finden !
Der Syntax lautet aber: Rdh:Rdl = Rdh:Rdl + K (aus Bascom-Hilfe).
Also
Wolfgang Schmidt schrieb:> Ich wollte den Code bez. der Laufzeit optimieren.
Dann würde ich für die Zähler freie Register im IO-Bereich des µC
verwenden, die mit 'in' und 'out' angesprochen werden können.
Zum Beispiel OCR1A und OCR1B oder auch ICR1. OSCCAL und TWBR könnten
noch frei sein.
C0:
in R24,OCR1BL ' Low byte erhöhen
inc R24
out OCR1BL,R24 'zurück schreiben
BRNE C1 'noch kein Überlauf
in R24,OCR1BH 'High byte erhöhen
inc R24
out OCR1BH,R24 'zurück schreiben
C1:
Wolfgang Schmidt schrieb:> Dann muss mein BASCOM ein anderes sein, denn ADIW ist im DAtenblatt des> Atmega8 zu finden !
Selbstverständlich geht ADIW, nur in der von Dir verwendeten Syntax ist
das unter Bascom nicht kompilierbar. Hättest Du es versucht, dann
wüsstest Du das.
spess53 schrieb:> Der Syntax lautet aber: Rdh:Rdl = Rdh:Rdl + K (aus Bascom-Hilfe).>> Also adiw R25:R24,1
Ich habe bereits geschrieben, dass mein BASCOM dann ein anderes ist.
Die Schreibweise aus der Hilfe habe ich zuerst benutzt, dann gab es eine
Fehlermedung.
Der im ersten Beitrag gepostete Code wird einwandfrei und ohne Fehler
und ohne Fehlermeldung in meinem BASCOM und mit meinem Atmega8
verarbeitet.
Mehr kann ich dir dazu nicht sagen.
W.
spess53 schrieb:> Hi>>>Dann muss mein BASCOM ein anderes sein, denn ADIW ist im DAtenblatt des>>Atmega8 zu finden !>> Der Syntax lautet aber: Rdh:Rdl = Rdh:Rdl + K (aus Bascom-Hilfe).> Also
Da hast Du in der falschen Spalte geschaut, richtig ist:
Rdl, K6
D.h. es wird bei ADIW/SBIW nur das LByte angegeben, das HByte wird
implizit angenommen. Das ist auch auf älteren Bascom-Versionen so,
deshalb kann man auch sagen, daß wie vom TE angegeben:
adiw R24:R25,1
nie kompiliert wurde. Fehlermeldung ist: "Low Pointer register
expected[R24:R25]
Während es so richtig wäre:
adiw R24,1
Wolfgang Schmidt schrieb:> Der im ersten Beitrag gepostete Code wird einwandfrei und ohne Fehler> und ohne Fehlermeldung in meinem BASCOM und mit meinem Atmega8> verarbeitet.
Da's keine handgedrechselten Bascom-Versionen gibt, kann man schlicht
und einfach sagen, daß der oben gepostete Code in dieser Form kein
Bascom gesehen hat.
In der Anlage findet ihr die Version, die ich für BASCOM geschrieben
habe.
Mein BASCOM (V2.07)compiliert ohne Probleme.
@MWS
Wer das Gegenteil behauptet, der möge bitte den Beweis auch antreten und
nicht vermutete Behauptungen in die Welt hinaus posaunen.
Ich habe einen sachlichen Thread eröffnet und keinen Thread um
Rechthabereien. Eine Entwicklung die leider bei vielen Beiträgen
festzustellen ist.
Wenn jemand mit einem sachlichen Beitrag zur Klärung von Fragen
beitragen kann, so ist er hier gerne willkommen.
Vermutungen habe ich selbst genug im Hinterkopf.
W.
Wolfgang Schmidt schrieb:> Wer das Gegenteil behauptet, der möge bitte den Beweis auch antreten und> nicht vermutete Behauptungen in die Welt hinaus posaunen.
Schon passiert.
Wolfgang Schmidt schrieb:> Ich habe einen sachlichen Thread eröffnet und keinen Thread um> Rechthabereien. Eine Entwicklung die leider bei vielen Beiträgen> festzustellen ist.
In etwa so wie schlampig gestellte Fragen und nicht gegebene
Informationen um die Helfer in die Wüste zu schicken.
> Vermutungen habe ich selbst genug im Hinterkopf.
Das ist offensichtlich :D
Hi
>'Erweiterung von Timer0 durch ein High-Byte auf 16 Bit
Nein. Du hast dir einen 16-Bit Softwarezähler gebaut, der durch Overflow
von Timer0 getriggert wird. Damit läuft dein 'Timer' mit 1/256 der
möglichen Auflösung. Du brauchst dir also eigentlich keine Mühe geben
ein paar Takte einzusparen.
MfG Spess
spess53 schrieb:> Nein. Du hast dir einen 16-Bit Softwarezähler gebaut, der durch Overflow> von Timer0 getriggert wird.
Besser gesagt, es wurde versucht einen zu bauen. Angefangen von nicht
kompilierbar, über unnötig umständliche Variablendeklaration bis hin zu
handwerklichen als auch Verständnisfehlern ist eigentlich alles
enthalten.
Da dürften ab und zu sinnfreie Ausgaben auf dem LCD auftauchen.
wenn ich einen geeigneten anderen regfile als
$regfile = "m8def.dat"
auswähle, dann kann ich genau die gleichen Fehlermeldugen erzeugen.
Mein BASCOM compiliert immer noch fehlerfrei und die LCD-Ausgaben sind
fehlerfrei und entsprechen den Erwarungen.
Warumm ich Zeit einsparen möchte, kann jeder von den Besserwissenden
selbst erkenne. Oder etwa nicht ?
W.
Hi
>Warumm ich Zeit einsparen möchte, kann jeder von den Besserwissenden>selbst erkenne. Oder etwa nicht ?
Du möchtest es. Tust aber das Gegenteil.
MfG Spess
Wolfgang Schmidt schrieb:> wenn ich einen geeigneten anderen regfile als> $regfile = "m8def.dat">> auswähle, dann kann ich genau die gleichen Fehlermeldugen erzeugen.
Wenn man das gepostete File compiliert, dann kommen die Fehlermeldungen.
Einstellungen in der IDE werden von Einstellungen im Code überschrieben.
> Warumm ich Zeit einsparen möchte, kann jeder von den Besserwissenden> selbst erkenne.
Hat Dir Spess schon geschrieben, nach 256 Takten ändert sich erst einer
der SW-Zähler. Also genug Zeit, was verstehst Du daran nicht ?
spess53 schrieb:> Damit läuft dein 'Timer' mit 1/256 der> möglichen Auflösung. Du brauchst dir also eigentlich keine Mühe geben> ein paar Takte einzusparen.
1
Locate 2 , 1 : Lcd Speed0 ; " "
Nicht-atomare Ausgabe eines 16-Bit Wertes. Hast Glück, daß die
Randbedingungen (Häufigkeit der ext. Ints) nicht zu (sichtbaren) Fehlern
führen.
1
$end Asm
2
3
Incr Lcd_out
Erst die Register sowie das SREG wieder herstellen, aber dann noch 'nen
Basic-Befehl draufsatteln, der mindestens ein Register verändert.
Da wirst Du also noch ein bisserl daran arbeiten müssen, bis Du Dich zum
von Dir geschaffenen Kreis der "Besserwissenden" zählen darfst ;D
Es gibt in dem gesamten Code einige Kontrollausgaben, die hier nur
kurzfristig eingefügt waren. Das sind alle LCD-Anweisungen.
Super erkannt habt ihr, dass alle 256 Takte ein Timer0-Interrupt
ausgelöst wird. Wenn dabei dann 20 oder 30 Takte für einen interrupt
gebraucht werden lohnt es sich, die Interruptzeit zu optimieren.
Ich habe euch natürlich alles mögliche verschwiegen !??
So zum Bsp. auch, dass nur der Ass-Code in ein anderes Programm
eingefügt wird und somit das gesamte Umfeld für die Fragestellung
bedeutungslos ist.
Dass sich daraus eine Zeitknappheit ergibt, das habe ich euch natürlich
auch verschwiegen. Dass Timer1 für zwei PWM-Kanäle und Timer2 für eine
interne Zeitbasis verwendet werden und unterbestimmten Bedingungen die
serielle Schnittstelle benötigt wird, das solltet ihr bei euren
Beiträgen durchaus berücksichtigen.
Aber wer meine Beiträge sorgfältig gelesen hat, dem wäre das bestimmt
schon früher aufgefallen.
Zugegeben, das "... $end Asm - Incr Lcd_out " war etwas unüberlegt.
Bei den wenigen Probeausgaben die ich damit gemacht habe, gabe es keine
Probleme.
Dass MWS sein BASCOM beim Compiliern oder das Bild so manipuliert hat,
dass viele Fehlermeldungen auftreten, das wundert mich. Da würde ich
doch glatt beim Hersteller reklamieren, die haben dir ein faules Ei zum
Download angeboten.
Was man nicht alles macht, um anscheinend Recht zu behalten.
Ich verabschiede mich aus diesem Thread.
W.
Wolfgang Schmidt schrieb:> Super erkannt habt ihr, dass alle 256 Takte ein Timer0-Interrupt> ausgelöst wird. Wenn dabei dann 20 oder 30 Takte für einen interrupt> gebraucht werden lohnt es sich, die Interruptzeit zu optimieren.
Nun, der Hintergrund war klar, die Frage war eher: warum machst Du's
dann nicht richtig ? D.h.: Takte sparen. Das war auch Spess's Frage,
deren Beantwortung Du schuldig bliebst.
Statt dessen wurschtelst Du 2 Softwarezähler hin, wobei einer gereicht
hätte und bei dem einen hätte es wiederum gereicht den 8Bit Zähler
selbst als Lowbyte zu verwenden und ihn nur um ein Highbyte auf 16Bit zu
erweitern.
> Dass MWS sein BASCOM beim Compiliern oder das Bild so manipuliert hat,> dass viele Fehlermeldungen auftreten, das wundert mich. Da würde ich> doch glatt beim Hersteller reklamieren, die haben dir ein faules Ei zum> Download angeboten.
Ich hab's versucht zu compilieren, 'nen Screenshot gemacht und
zusätzlich auf die korrekte Verwendung laut Bascom-Hilfe hingewiesen. Du
verstehst was genau daran nicht ?
> So zum Bsp. auch, dass nur der Ass-Code in ein anderes Programm> eingefügt wird und somit das gesamte Umfeld für die Fragestellung> bedeutungslos ist.
Du hast die Hilfswilligen erstmal in die Wüste geschickt, denn auch ich
hätte dahinter keinen Bascom-Code vermutet, schon aufgrund der
unzulässigen Syntax. Und die Sprache ist nun mal nicht belanglos.
> Ich verabschiede mich aus diesem Thread.
Betrachte ich nicht als Verlust :D
Hi,
is en thread wie so viele hier.
sinnvolle frage am anfang, verschiedene meinungen und dann persönliche
angriffe.
hab mich den ganzen tag zurück gehalten.
in den beiträgen der "helfer" waren aber mehr irrtümer und falsche
annahmen als fehler in dem anfangs und später geposteten code.
die fehlermeldungen von mws sind ganz schön manipuliert. in anderen
zusammenhängen nennt man das urkundenfälschung.
hab den code mit bascom 2.05 compiliert, war fehlerfrei.
seine irrtümer hat w. doch eingestanden und er wird auch sinnvolle
vorschläge nutzen.
wer hatte mov vorgeschlagen? ist vollkommener quatsch!
spess, mws haben dann immer weiter in den krümeln gesucht um nicht auf
die eigenen irrtümer oder falsche annahmen zu müssen.
w. hat ja so viel verschwiegen, - was man als leser hätte selbst
erkennen können -
und zwei 16bit softwarezähler, die ja nicht synchron laufen und einzeln
gelöscht werden können, wie jeder kundige leser erkennen sollte, mit
einem 8bit timer zu realisieren ist doch hier gut gelungen.
takte bei 20 - 30 von 256 einzusparen ist doch en sinnvolles ziel, wie
jeder kundige leser erkennen sollte.
schönen abend
uwe
Uwe schrieb:> hab mich den ganzen tag zurück gehalten.
Man hat auf Dich gewartet.
Uwe schrieb:> die fehlermeldungen von mws sind ganz schön manipuliert.
So, so.
Uwe schrieb:> , wie> jeder kundige leser erkennen sollte.> , wie jeder kundige leser erkennen sollte, mit> einem 8bit timer
Gibt aber viele "Kundige" bei Dir, ist das so was wie "Besserwissende" ?
Der Thread war doch durchaus nützlich, der TE wurde auf einige Fehler
hingewiesen, es gab sinnvolle Ratschläge, also alles ok.
Nur der wirklich sinn- und Inhalt-loseste Beitrag fehlte noch, und da Du
den glücklicherweise geschrieben hast, ist nun auch das erledigt.