Hallo zusammen
Ich arbeite mich momentan durch das Tutorial und habe eine
Verständnisfrage zum Tutorial. Und zwar will ich das Fast-PWM Beispiel
so modifizieren, dass ich eben auf eine 8 Bit PWM komme. Das
funktioniert auch soweit, einfach stellt sich mir folgende Frage:
Bei der 8 Bit PWM hat der Compare-Wert ja im LowByte des OCR1A Registers
Platz. Das heisst ja auch, dass es theoretisch reichen würde, nur das
LowByte neu zu beschreiben, wenn man den Compare-Wert ändern will, das
High-Byte muss ja immer auf 0 sein. Jetzt habe ich schon an diversen
Stellen gelesen, dass immer zuerst das High-Byte beschrieben werden
soll, dann das LowByte, weil es sonst unter umständen zu falschen Werten
kommen kann. Beim ADC leuchtet mir das auch ein, aber ich kann mir bei
diesem Register nicht vorstellen, dass es einen Einfluss hat, wenn ich
innerhalb einer Interrupt-Routine nur das LowByte ändere. Oder übersehe
ich da etwas, was in späteren, komplexeren Programmen Probleme machen
könnte? Mit anderen Worten, gilt diese allgemeine Regel auch für das
OCR1AH/L-Register?
Gruss Johannes
1
.include "m8def.inc"
2
3
;LED an OC1A, pulsiert zwischen lowerlimit und upperlimit
4
.def temp = r16
5
.def dir = r17
6
.def zero = r18
7
.def lowerlimit = r19
8
.def upperlimit = r20
9
10
.org 0x000
11
rjmp RESET
12
.org OVF0addr
13
rjmp INTERRUPT
14
15
RESET:
16
ldi temp, HIGH(RAMEND)
17
out SPH, temp
18
ldi temp, LOW(RAMEND)
19
out SPL, temp
20
21
ldi zero, 0x00
22
ldi lowerlimit, 0x00
23
ldi upperlimit, 0x20
24
ldi dir, 0x00
25
26
;Timer1 initialisieren
27
;Modus 5, kein prescaler
28
ldi temp, 1<<COM1A1 | 1<<WGM10
29
out TCCR1A, temp
30
31
ldi temp, 1<<WGM12 | 1<<CS10
32
out TCCR1B, temp
33
34
35
;Comparewert füe OC1A
36
ldi temp, 0x00
37
out OCR1AH, temp
38
ldi temp, 0X01
39
out OCR1AL, temp
40
41
ldi temp, 0x02
42
out DDRB, temp
43
44
; Timer0 Aufsetzen
45
ldi temp, 1<<CS02 | 1<<CS00 ;prescaler 1024
46
out TCCR0, temp
47
48
ldi temp, 1<<TOIE0
49
out TIMSK, temp
50
51
sei
52
53
54
main:
55
rjmp main
56
57
INTERRUPT:
58
in temp, OCR1AL
59
sbrs dir, 0 ;wenn das 0. bit 0 ist
60
inc temp ; erhöhen
61
sbrc dir, 0 ; wenn das 0. bit 1 ist
62
dec temp ; verringern
63
64
cp temp, upperlimit
65
breq TOGGLEDIR
66
cp temp, lowerlimit
67
breq TOGGLEDIR
68
69
INTERRUPTEND:
70
out OCR1AH, zero ;high-byte zuerst beschreiben (mit nullen, da 8Bit PWM)
Es gibt hardwareseitig in der Tat ein temporäres Reister in dem der High
Value zwischengespeichert wird. Erst wenn dann der Access auf das
Low-Byte Register erfolgt, werden beide Werte zusammen, und in das 16Bit
register geschrieben.
Sofern du also nicht sichergehen kannst, dass der Inhalt des internen
temporären Registers 0x00 ist, solltest du lieber auch das High-Byte
schreiben.
Siehe Datenblatt:
> The Output Compare Registers are 16-bit in size. To ensure that both the> high and Low bytes are written simultaneously when the CPU writes to these> registers, the access is performed using an 8-bit temporary High byte> register (TEMP). This temporary register is shared by all the other 16-bit> registers. See “Accessing 16-bit Registers” on page 77.> When the Low byte of a 16-bit register is written by the CPU, the High> byte stored in the temporary register, and the Low byte written are both> copied into the 16-bit register in the same clock cycle.> Accessing the Low byte triggers the 16-bit read or write operation. When> the Low byte of a 16-bit register is written by the CPU, the High byte> stored in the temporary register, and the Low byte written are both copied> into the 16-bit register in the same clock cycle.
Ok, wunderbar, dann ist jetzt alles klar.
Das würde heissen, in diesem Beispiel könnte ich es mir sparen, das
High-Register auch bei jedem Interrupt zu schreiben, das ist aber keine
gute Idee, sich das anzueignen, da sonst eine nicht unbedingt leicht zu
findende Fehlerquelle entsteht. Besser ist es, das generell zu
schreiben, dann ist man auf der sicheren Seite.
Vielen Dank.
Gruss Johannes
Hi
>Bei der 8 Bit PWM hat der Compare-Wert ja im LowByte des OCR1A Registers>Platz. Das heisst ja auch, dass es theoretisch reichen würde, nur das>LowByte neu zu beschreiben, wenn man den Compare-Wert ändern will, das>High-Byte muss ja immer auf 0 sein. Jetzt habe ich schon an diversen>Stellen gelesen, dass immer zuerst das High-Byte beschrieben werden>soll, dann das LowByte, weil es sonst unter umständen zu falschen Werten>kommen kann.
Bei einer 8Bit-PWM auf einem 16-Bit Timer ist es egal, was in OCRnH
steht. Die High-Register werden schlichtweg ignoriert.
MfG Spess
Ok, das heisst im Falle der 8-Bit PWM (und nur dann) kann man das
High-Register in jedem Fall vernachlässigen. Gut, dann ist mir das jetzt
klar, vielen Dank für die Antworten.
Gruss Johannes
Spess hat Recht:
> Note that when using fixed TOP values the unused bits are masked to zero when
any of the OCR1x Registers are written.
Mit "fixed TOP values" sind hier die Modi gemeint bei der die PWM
resolution fest vorgegeben ist. Also z.B. deine 8bit. Das High-Byte ist
somit garantiert 0x00.