Forum: Mikrocontroller und Digitale Elektronik AVR-LOGIC Frage


von Mathias (Gast)


Lesenswert?

Hallo Forum,

ich habe folgendes Verständnisproblem:

Ich möchte das WDTCR über ein register verändern, möchte aber alle 
ursprünglichen Werte, außer den CS-bits behalten!


WD_SET:      IN temp,WDTCR ;Register einlesen
      OR temp,registerX
      OUT WDTCR, temp

leider funktioniert es nicht. Kann mir jemand helfen?

von spess53 (Gast)


Lesenswert?

Hi

>Ich möchte das WDTCR über ein register verändern, möchte aber alle
>ursprünglichen Werte, außer den CS-bits behalten!

Welch CS-Bits?

>WD_SET:      IN temp,WDTCR ;Register einlesen
>      OR temp,registerX
>      OUT WDTCR, temp

Normalerweise benutzt man 'and' mit einem Wert bei dem die zu erhaltenen 
Bits auf 1 gesetzt sind.

MfG Spess

von Christian K. (the_kirsch)


Lesenswert?

Welcher Kontroller, bei meinem ATMega heißt es "WDTCSR" (Watchdog Timer 
Control Register)


Ansonsten, was ist bei dir Temp, auch ein Register?



WD_SET:
    IN rX, WDTCSR
    OR rX, rY // oder mit einer konstante "ORI rX, K"
    OUT WDTCSR, rX


EDIT
mit OR setzt man Bits
mit AND löscht man Bits (die Bits die gelöscht werden sollen sind in der 
Bitmaske 0, alle anderen 1)

von Martin S. (led_martin)


Lesenswert?

Wenn Du bestimmte Bits in einem Register erhalten, andere aber generell 
aus einem anderen übernehmen willst brauchst Du dazu 2 
Logik-Operationen.

Als Beispiel:

Die oberen 4 Bit sollen unverändert bleiben, die unteren 4 ersetzt 
werden:
1
ANDI  temp, 0b11110000  ; Setzt die untern 4 Bits auf '0', lässt die oberen unverändert
2
OR    temp, registerX   ; Übernimmt die Bits, die in registerX '1' sind

Vorraussetzung ist, daß in registerX keins der oberen 4 Bits gesetzt 
ist.

Mit freundlichen Grüßen - Martin

von Mathias (Gast)


Lesenswert?

VIelen Dank. Das passt.

Controller ist Attiny 13A

von Mathias (Gast)


Lesenswert?

Also der Fehler liegt in diesem Falle beim AVR-Studio

;Setzt Timer auf den in reg"data" übergebenen Wert.

TIMERX:     IN R16,TCCR0B      ;Timerwert einlesen
      ANDI R16,0b11111000    ;untere bits löschen, obere beibehalten
      ANDI data,0b00000111    ;obere bits löschen, untere beibehalten
      OR R16,data      ;Daten verknüpfen
      ;---
      OUT TCCR0B,R16      ;Wert zurückschreiben

Anscheinend schreibt das AVR_Studio (4) den "neuen" Wert nicht korrekt 
ins Register TCCR0B zurück.

von spess53 (Gast)


Lesenswert?

Hi

>Anscheinend schreibt das AVR_Studio (4) den "neuen" Wert nicht korrekt
>ins Register TCCR0B zurück.

Woran machst du das fest?

MfG Spess

von Martin S. (led_martin)


Lesenswert?

Also das von Dir gezeigte Stück Programm muß funktionieren. Damit der 
Timer macht, was man erwartet, müssen aber alle Konfigurations-Bits 
richtig gesetzt sein, der Fehler kann also auch woanders liegen. Stimmt 
der Modus, in dem der Timer betrieben wird, die WGMxx Bits? Beachtest Du 
die Empfehlungen im Datenblatt, bestimmte Bits nur bei gestopptem Timer 
zu setzen? Hast Du bedacht, daß die Inhalte von den OCR0A / OCR0B 
Registern, je nach Mode-Einstellung, nicht sofort übernommen werden? 
Oder werden die Bits, an anderer Stelle des Programms, verändert, 
vielleicht aus Versehen z.B. TCCR0B geschrieben, obwohl es eigentlich 
TCCR0A heißen sollte, oder TCCR1B.

Mit freundlichen Grüßen - Martin

von Mathias (Gast)


Lesenswert?

Vielen Dank für die Antworten!

Also die Konfiguration der Timerrelevanten Registern stimmt alles.

Bei der Simulation in AVR-STudio 4 rechnet er richtig, z.B. ist das 
Ergebnis der Bitverknüpfung z.B. 0b10000111, jedoch überträgt das AVR 
Studio das Byte einfach nicht richtig. Er "verschluckt" quasi einige 
Bits, obwohl diese in den Registern auf "1" stehen. D.h. er überträgt 
0x83 ins TCCR0B und danach sind nur 0x03 im TCCR0B vorhanden!
Ich simuliere das einfach mal mit Studio 6 und sehe nach, was dieses 
daraus macht.

von Dieter F. (Gast)


Lesenswert?

Du hast Dir aber schon angeschaut, was mit dem Bit 7 in TCCR0B ausgelöst 
wird bzw. welche "Eigenheiten" dieses Bit hat:

 Bit 7 – FOC0A: Force Output Compare A
The FOC0A bit is only active when the WGM bits specify a non-PWM mode.
However, for ensuring compatibility with future devices, this bit must 
be set to zero when TCCR0B is written when operating in PWM mode.

When writing a logical one to the FOC0A bit, an immediate Compare Match 
is forced on the Waveform Generation unit.

The OC0A output is changed according to its COM0A[1:0] bits setting. 
Note that the FOC0A bit is implemented as a strobe. Therefore it is the 
value present in the COM0A[1:0] bits that determines the effect of the 
forced compare.

A FOC0A strobe will not generate any interrupt, nor will it clear the 
timer in CTC mode using OCR0A as TOP.

The FOC0A bit is always read as zero.

von Martin S. (led_martin)


Lesenswert?

Dieter Frohnapfel schrieb:
> The FOC0A bit is always read as zero.

Das ist genau das, was Du beobachtest! Solche 'Feinheiten' der Periferie 
werden nicht von allen Simulatoren sauber nachgestellt. Mir ist, bis 
jetzt, noch kein Simulator begegnet der da Alles richtig macht, beim 
Einen sind die Timer sauber, dafür macht der ADC merkwürdige Sachen, 
beim Anderen passt's mit dem ADC, dafür ist der UART unbrauchbar, ... 
Was letztendlich zählt, ist das 'reale' System, da muß es funktionieren.

Mit freundlichen Grüßen - Martin

von Mathias (Gast)


Lesenswert?

> ".Du hast Dir aber schon angeschaut, was mit dem Bit 7 in TCCR0B ausgelöst
wird bzw. welche "Eigenheiten" dieses Bit hat..."

Ja habe ich. Genau deshalb will ich nicht, daß eine Routine die bits 
ändert!
Deshalb der Umweg über eine eigene Funktion, der man den Wert "übergibt" 
und welche NUR die CS-bits ändern kann (per Ausmaskieren).

Grüsse Mathias

von Dieter F. (Gast)


Lesenswert?

Mathias schrieb:
> Ja habe ich. Genau deshalb will ich nicht, daß eine Routine die bits
> ändert!

Das widerspricht aber dem:

Mathias schrieb:
> D.h. er überträgt
> 0x83 ins TCCR0B und danach sind nur 0x03 im TCCR0B vorhanden!

Was denn nun?

von Martin S. (led_martin)


Lesenswert?

Mathias schrieb:
> Ja habe ich. Genau deshalb will ich nicht, daß eine Routine die bits
> ändert!
> Deshalb der Umweg über eine eigene Funktion, der man den Wert "übergibt"
> und welche NUR die CS-bits ändern kann (per Ausmaskieren).

Wenn Du die FOC0A-, und FOC0B-Bits (Bit 7 und 6) in Ruhe lässt, 
funktioniert das auch. Beim lesen werden die immer als '0' gelesen, und 
wenn Du da nichts hinein-veroderst, wird auch wieder '0' geschrieben, 
was keine Aktion auslöst. Wenn Du diese Bits setzen möchtest, um ihre 
Funktion zu benutzen, muß Dir klar sein, daß sie trotzdem als '0' 
gelesen werden, das macht nicht irgendeine Routine, sondern der 
Mikrocontroller. Daß das in manchen Simulationen anders ist, liegt am 
Simulator, der da fehlerhaft ist. Peripherie-Register sind keine 
Speicherstellen, bei denen man generell davon ausgehen kann, daß ein 
dort geschriebener Wert auch so wieder gelesen werden kann. Bei manchen 
Registern, wie z.B. das UART-Datenregister, gehen Schreib- und 
Lese-Operationen an ganz unterschiedliche Hardware-Register, trotz 
gleicher Adresse.

Mit freundlichen Grüßen - Martin

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
Noch kein Account? Hier anmelden.