Zwei Register in eine Variable schreiben

Gast #308795
Lesenswert?

Hallo,

hab eine Bascom spezifische frage:

In den Registern ICR1L und ICR1H liegt der Timerstand zum Zeitpunkt
einer Captureflanke. Ich brauche diesen Wert für weitere Berechnungen
zusammengefasst in einem Word. also in 2Byte. Wie kann ich das in
Bascom realisieren?

Danke für Hilfe!

Toby
#308796
Lesenswert?

Es geht am einfachsten, wenn man der Word Variable, welche den Wert
aufnehmen soll, 2 Bytes überlagert.

Dim Wert as Word
Dim WertLow as Byte at WordWert Overlay
Dim WertHigh as Byte at WordWert + 1 Overlay

' Und nun der Lesevorgang
WertLow = ICR1L
WertHigh = ICR1H

' und nun kann der 16-Bit Wert benutzt werden
Print Wert

Es muss beachtet werden, dass bei den 16-Bit I/O Registern zuerst der
Low-Wert und anschließend der High-Wert gelesen muss.
Beim Beschreiben muss zuerst der High-Wert und anschließend der
Low-Wert geschreiben werden.
Gast #308801
Lesenswert?

Ich weiß nicht wie ich das anders programmieren soll. Du schriebst
"Wordwert"... aber wie implementiere ich das genau? Ich weiß ja nicht
wo das word letzten endes liegt. ich verwende einen atmega 128.

danke für den konstanten support hier!!!
#308802
Lesenswert?

Beim Mega128 beginnt das SRAM ab &H100.
Im Normalfall ist es nicht nötig, die Variable auf eine bestimmte
Adresse zu legen.

Mit

Dim Wert as Word

legt BASCOM-AVR die Word Variable auf die nächste freie
Speicheradresse.

Mit

Dim WertLow as Byte at WordWert Overlay
Dim WertHigh as Byte at WordWert + 1 Overlay

hast Du 2 Byte-Variable, welche keinen eigenen Speicherplatz belegen,
sondern deren Adresse auf das LOW Byte und das HIGH Byte der Word
Variable WERT verweisen. Das Beschreiben dieser Overlay Bytes schreibt
also direkt in die Word Variable. Du hast also 2 Bytes im SRAM, welche
einerseits unter der Word-Variable WERT ansprechbar sind, aber
andererseits auch getrennt mit den überlagerten Byte-Variablen WertLow
und WertHigh.
Für die Variable kannst Du natürlich andereNamen verwenden.
Gast #308803
Lesenswert?

Vielen Dank für die Erläuterung!
Leider funktioniert es nicht. Ich hab in Bascom folgendes definiert:

Dim Long_Timer1 as word
Dim Timer1low as byte at WordLong_timer1 Overlay
Dim Timer1high as byte at WordLong_timer1 +1 Overlay


jetzt gibts 3 fehlermeldungen. 2 mal bekomme ich, adress out of bounds
und einmal illegal character [+]

als ich die Variablen an H198 bzw. H199 festgelegt habe, gab es keine
fehlermeldung.
Wo liegt der fehler?
Gast #308805
Lesenswert?

hmm, ich verwende 1.11.7.4. dann liegt es wohl an der kompilierung.
das is natürlich blöd... ich kanns ja fürs erste mal von hand
festlegen, und wenn ich dann fertig bin mit dem programm, kann ich ja
aus dem mem-mapping ablesen, wo die nächste eigentlich freie stelle im
speicher wäre...
BTW: bis wohin geht der Adressierbare SRAM-Bereich?
#308806
Lesenswert?

Das hängt von der AVR-Type ab.

Schau im Compiler-Report und ziehe von Frame-Start noch den Framesize
ab. Oder ziehe von der höchsten Speicheraddresse (Siehe RAMEND im DAT
File) die Werte für Stack size,  S-Stacksize und Framesize ab. Dann
hast die höchste freie SRAM Adresse. Mehr Informationen zu den Stacks
gibt es auf http://www.roboternetz.de/wissen/index.php/Bascom_Inside
Gast #308807
Lesenswert?

Oh weh, macht Ihr es hier komliziert.

In Capture1 fasst Bascom den Wert doch schon zu einem Word zusammen.

Also z.B. einfach:

<code>
On Icp1 Oncapture                            'Interrupt-Routine
Config Timer1 = Timer , Capture Edge = Falling , Prescale = 256
.....
Dim Wcount as Word
.....
.....
.....
Oncapture:                                   'Timer1-Capture
  Disable Interrupts                         'nötig für Auslesen von
Cap1
  Wcount = Capture1                          'Wert sichern
  Timer1 = 0                                 'Timer-Reset
  Enable Interrupts                          'Interrupts wieder
aktivieren
Return
</code>

Grüße
Henrik

PS: In diesem Forum wird grundsätzlich alles verkompliziert.
#308809
Lesenswert?

Danke für den Hinweis. Mir war das Capture1 nicht geläufig.

Das Disable und Enable von Interrupt in der Interrupt-Service-Routine
ist meines Erachtens nicht nötig, da mit dem Aufruf des
Interrupt-Routine der Interrupt automatisch Disabled wird und mit dem
RETURN, welche diese abschließt, BASCOM ein reti generiert, welcher den
Interrupt wieder Enabled.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren