Forum: Mikrocontroller und Digitale Elektronik AVR:Frage zum Timer/Prescaler (Assembler)


von peter (Gast)


Lesenswert?

Guten Tag!

Ich steige gerade in AVR ein und habe eine Frage zum Timer, bzw. 
generell zu Assembler. Im Tutorial steht für den Prescaler = 1 folgender 
Befehl:
1
ldi     temp, (1<<CS00)
2
out     TCCR0, temp
Dem Datenblatt des ATmega8 entnehme ich, dass ich für einen Prescaler 
von 1024 folgende Kombination brauche:
CS02: 1
CS01: 0
CS00: 1
Jetzt komme ich nicht ganz mit dem Assemblerbefehlen klar. Leider 
verstehe ich die Schreibweise (1<<CS00) nicht genau. Ich habe bereits 
zwei Dinge versucht: 1. mit gleicher Schreibweise, geht aber leider 
nicht:
1
ldi temp, (1<<CS00) | (1<<CS02) ;Ich will ja CS00 =1 und CS02 =1 für
2
out TCCR0, temp                 ;den Vorteiler von 1024
und 2. das bitmuster ins register zu schreiben
1
ldi temp, 0b00000101
2
out TCCR0, temp
Das funktioniert leider auch nicht.

Kann mir jemand erklären, wie ich den Prescaler jetzt konkret 
programmiere und dabei auch die mir nicht ganz klare Schreibweise 
erläutern? Dankeschön!

Gruß Peter

PS: Sorry, falls dieser Beitrag in der "Codesammlung" besser aufgehoben 
wäre, war mir nicht sicher. Notfalls bitte einfach verschieben!

von Karl H. (kbuchegg)


Lesenswert?

peter schrieb:

> Dem Datenblatt des ATmega8 entnehme ich, dass ich für einen Prescaler
> von 1024 folgende Kombination brauche:
> CS02: 1
> CS01: 0
> CS00: 1

Jemand, der ins Datenblatt sieht! Weiter so!

> Jetzt komme ich nicht ganz mit dem Assemblerbefehlen klar. Leider
> verstehe ich die Schreibweise (1<<CS00) nicht genau.

Du kannst es fürs erste als Phrase nehmen für:
Das ergibt ein Bitmuster, bei dem das Bit CS00 gesetzt ist. Den Namen 
des Bits CS00 hast du aus dem Datenblatt.

> Ich habe bereits
> zwei Dinge versucht: 1. mit gleicher Schreibweise, geht aber leider
> nicht:

Was bedeutet "geht nicht"?

>
1
> ldi temp, (1<<CS00) | (1<<CS02) ;Ich will ja CS00 =1 und CS02 =1 für
2
> out TCCR0, temp                 ;den Vorteiler von 1024
3
>

ist korrekt

> und 2. das bitmuster ins register zu schreiben
>
1
> ldi temp, 0b00000101
2
> out TCCR0, temp
3
>

Ist auch korrekt. Aber die erste Schreibweise ist ungleich besser, weil 
man dort im Text sieht, dass sowohl CS00 als auch CS02 gesetzt werden. 
In der 2.ten Schreibweise muss man erst das Datenblatt studieren um 
rauszufinden, dass die beiden 1 Bits mit CS00 und CS02 korrespondieren, 
ehe man dann in die Tabelle gehen kann, in der steht, welche Wirkung das 
hat.

> Das funktioniert leider auch nicht.

Da beide Schreibweisen absolut 100%ig identisches Ergebnis liefern, mag 
das dann ein Hinweis darauf sein, dass in deinem Programm was ganz 
anderes faul ist.


> PS: Sorry, falls dieser Beitrag in der "Codesammlung" besser aufgehoben
> wäre, war mir nicht sicher. Notfalls bitte einfach verschieben!

Passt schon. Die Codesammlung dient dazu, fertige Programme zu 
veröffentlichen, die für andere von Interesse oder von Nutzen sein 
könnten. Nicht wirklich das, worum es bei dir geht.

von peter (Gast)


Lesenswert?

Die Schreibweise ist mir zwar noch etwas unklar, aber variante 1 geht 
dennoch. Es ist im AVRStudio (4) Debugger nur ziemlich blöd dargestellt:
Ist CS00 = 1 steht da "Running, No Prescaling" und bei CS02 = 1 einfach 
nur ein Haken bei "Clock Select0 Bit 2". Also ist der Prescaler auf 1024 
obwohl eigentlich dort steht "No Prescaling".

von peter (Gast)


Lesenswert?

Huch, da haben wir ja fast zeitgleich geantwortet.
Also vielen Dank für die Info!

von ich (Gast)


Lesenswert?

Wieso ist dir die Schreibweise unklar.

Das Register "TCCR0" besteht aus 8 Bits, jedes Bit hat einen Namen, wie 
z.B. "CS00" oder "CS02". Wenn du ein bestimmtes Bit aus 1 setzen willst 
oder muss, schreibst du einfach (1<<CS00). Damit siehst du gleich, das 
das Bit auf 1 gesetzt ist oder wird.

von Klaus 2. (klaus2m5)


Lesenswert?

ich schrieb:
> ldi temp, (1<<CS00) | (1<<CS02) ;Ich will ja CS00 =1 und CS02 =1 für...

Machen wir einen Versuch...

CS0x ist in *def.inc wie folgt definiert (* =AVRtyp):

; TCCR0 - Timer/Counter0 Control Register
.equ  CS00  = 0  ; Clock Select0 bit 0
.equ  CS01  = 1  ; Clock Select0 bit 1
.equ  CS02  = 2  ; Clock Select0 bit 2

<< = linksschieben, | = oder

1<<CS00 = schiebe eine 1 um 0 (CS00) Positionen nach links = 0b00000001
1<<CS02 = schiebe eine 1 um 2 (CS02) Positionen nach links = 0b00000100
(1<<CS00) | (1<<CS02) = verodere das Ergebnis              = 0b00000101

Ich persönlich bevorzuge die zweite Schreibweise mit einem venünftigen 
Kommentar und nicht die C-verseuchte Version!

von peter (Gast)


Lesenswert?

Danke Klaus 2m5. Das mit dem schieben per << und dem oder | war mir 
bisher neu.

von spess53 (Gast)


Lesenswert?

HI

>Danke Klaus 2m5. Das mit dem schieben per << und dem oder | war mir
>bisher neu.

Da wird es mal Zeit sich die AVR-Studio-Hilfe zu den AVR Assemblern 
anzusehen.

MfG Spess

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.