Forum: Mikrocontroller und Digitale Elektronik ATMega Timer 1 Konfiguration


von Mathias D. (pfmd86)


Lesenswert?

Hallo,

ich würde gern den Timer1 über zwei Taster beeinflussen. Dabei ist mir 
beim folgenden Code was aufgefallen was ich mir nicht erklären kann.
1
    ldi      value, 250
2
    out      OCR1AH, value
3
    ldi      temp1, 0xFF
4
    out      OCR1AL, temp1

Sobald das Programm bei in Zeile 3 ankommt verschwindet der Wert im 
OCR1AH. Warum ist das so? Erst schreibt er 250 rein und bei Zeile drei 
ist er wieder auf 0.

Der ganze Quelltext sollte so aussehen:
Funktion: Zwei Taster beeinflussen die PWM Zeiten...
1
.include "m8def.inc"
2
 
3
.def temp1 = r17
4
.def value = r16
5
6
 
7
    rjmp    init
8
 
9
;
10
 
11
init:
12
    ldi      temp1, HIGH(RAMEND)     ; Stackpointer initialisieren
13
    out      SPH, temp1
14
    ldi      temp1, LOW(RAMEND)
15
    out      SPL, temp1
16
  
17
    ;
18
    ; Timer 1 einstellen
19
    ;
20
    ; Modus 14:
21
    ;    Fast PWM, Top von ICR1
22
    ;
23
    ;     WGM13    WGM12   WGM11    WGM10
24
    ;      1        1       1        0
25
    ;
26
    ;    Timer Vorteiler: 256
27
    ;     CS12     CS11    CS10
28
    ;      1        0       0
29
    ;
30
    ; Steuerung des Ausgangsport: Set at BOTTOM, Clear at match
31
    ;     COM1A1   COM1A0
32
    ;      1        0
33
    ;
34
 
35
    ldi      temp1, 1<<COM1A1 | 1<<WGM11
36
    out      TCCR1A, temp1
37
 
38
    ldi      temp1, 1<<WGM13 | 1<<WGM12 | 1<<CS10
39
    out      TCCR1B, temp1
40
 
41
    ;
42
    ; den Endwert (TOP) für den Zähler setzen
43
    ; der Zähler zählt bis zu diesem Wert
44
    ;
45
    ldi      temp1, 0xFF
46
    out      ICR1H, temp1
47
    ldi      temp1, 0xFF
48
    out      ICR1L, temp1
49
 
50
  ldi temp1, 0x00
51
  out DDRD, temp1
52
  ldi temp1, 0xff
53
  out PORTD, temp1
54
55
  ldi temp1, 0xff
56
  out DDRB, temp1
57
58
    ;
59
    ; der Compare Wert
60
    ; Wenn der Zähler diesen Wert erreicht, wird mit
61
    ; obiger Konfiguration der OC1A Ausgang abgeschaltet
62
    ; Sobald der Zähler wieder bei 0 startet, wird der
63
    ; Ausgang wieder auf 1 gesetzt
64
    ;
65
    ldi      value, 250
66
    out      OCR1AH, value
67
    ldi      temp1, 0xFF
68
    out      OCR1AL, temp1
69
    ; Den Pin OC1A zu guter letzt noch auf Ausgang schalten
70
    ldi      temp1, 0b00110010
71
    out      DDRB, temp1
72
 
73
main:
74
  sbis   PIND,2
75
        rjmp    plus
76
  sbis  PIND,3
77
  rjmp  minus
78
  rjmp  main
79
plus:
80
  sbi  PORTB,5 ;Sperr-LED an
81
        inc  value
82
  rcall  setvalue
83
  cbi  PORTB,5 ;Sperr-LED aus
84
  rjmp  main
85
86
minus:
87
  sbi  PORTB,4 ;Sperr-LED an
88
  dec  value
89
  rcall  setvalue
90
  cbi  PORTB,4 ;Sperr-LED aus
91
  rjmp  main
92
93
setvalue:
94
  out      OCR1AH, value
95
  rcall   wait
96
  ret
97
98
wait:
99
          ldi  R17, 13
100
WGLOOP0:  ldi  R18, 20
101
WGLOOP1:  ldi  R19, 250
102
WGLOOP2:  dec  R19
103
          brne WGLOOP2
104
          dec  R18
105
          brne WGLOOP1
106
          dec  R17
107
          brne WGLOOP0
108
          nop
109
          nop
110
          ret

von spess53 (Gast)


Lesenswert?

Hi

>Sobald das Programm bei in Zeile 3 ankommt verschwindet der Wert im
>OCR1AH. Warum ist das so? Erst schreibt er 250 rein und bei Zeile drei
>ist er wieder auf 0.

Siehst du das im Simulator? Wenn ja, solltest du beachten, das PWM-Modi 
mit variablen Top vom Simulator nicht unterstützt werden.

MfG Spess

von Stefan E. (sternst)


Lesenswert?

Mathias D. schrieb:
> Sobald das Programm bei in Zeile 3 ankommt verschwindet der Wert im
> OCR1AH. Warum ist das so? Erst schreibt er 250 rein und bei Zeile drei
> ist er wieder auf 0.

Weil ein neuer Wert für OCR1A in einem PWM-Modus nicht sofort in das 
Register geschrieben wird, sondern erst beim nächsten Timer-Überlauf. 
Bis zu diesem Zeitpunkt steht der Wert in einem nicht sichtbaren 
Schattenregister.

von Mathias D. (pfmd86)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Sobald das Programm bei in Zeile 3 ankommt verschwindet der Wert im
>>OCR1AH. Warum ist das so? Erst schreibt er 250 rein und bei Zeile drei
>>ist er wieder auf 0.
>
> Siehst du das im Simulator? Wenn ja, solltest du beachten, das PWM-Modi
> mit variablen Top vom Simulator nicht unterstützt werden.
>
> MfG Spess

ja, im Simulator hab ich mir den OCR1AH in ein Watch genommen um zu 
sehen ob das so geht wie ich mir das gedacht habe. Aber auch wenn ich es 
brenne scheint es so nicht zu klappen wie ich mir das denke.

von spess53 (Gast)


Lesenswert?

Hi

>Aber auch wenn ich es
>brenne scheint es so nicht zu klappen wie ich mir das denke.

Kommt darauf an, was du erwartest und wie du das misst. Mit deinen 
Werten für ICR1 und OCR1A bekommst du eine ON-Zeit von 98% des Taktes. 
Ohne Oszi kannst du das nicht messen.

MfG Spess

von Mathias D. (pfmd86)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Aber auch wenn ich es
>>brenne scheint es so nicht zu klappen wie ich mir das denke.
>
> Kommt darauf an, was du erwartest und wie du das misst. Mit deinen
> Werten für ICR1 und OCR1A bekommst du eine ON-Zeit von 98% des Taktes.
> Ohne Oszi kannst du das nicht messen.
>
> MfG Spess

Also Ziel des ganzen war es eigentlich die LED mit PWM zu dimmen. Und 
die Einstellungen über zwei Taster vorzunehmen. Ich muss auch zugeben, 
das ich den PWM mit dem Timer 1 noch nicht gecheckt habe... :-(

von spess53 (Gast)


Lesenswert?

Hi

>Also Ziel des ganzen war es eigentlich die LED mit PWM zu dimmen. Und
>die Einstellungen über zwei Taster vorzunehmen. Ich muss auch zugeben,
>das ich den PWM mit dem Timer 1 noch nicht gecheckt habe... :-(

Dann bringe doch erst mal deine PWM zum laufen. Mit
1
    ldi      value,High($8000)
2
    out      OCR1AH, value
3
    ldi      temp1, Low($8000)
4
    out      OCR1AL, temp1

sollte deine LED merklich dunkler leuchten.

mfG Spess

von Mathias D. (pfmd86)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Also Ziel des ganzen war es eigentlich die LED mit PWM zu dimmen. Und
>>die Einstellungen über zwei Taster vorzunehmen. Ich muss auch zugeben,
>>das ich den PWM mit dem Timer 1 noch nicht gecheckt habe... :-(
>
> Dann bringe doch erst mal deine PWM zum laufen. Mit
>
>
1
>     ldi      value,High($8000)
2
>     out      OCR1AH, value
3
>     ldi      temp1, Low($8000)
4
>     out      OCR1AL, temp1
5
>
>
> sollte deine LED merklich dunkler leuchten.
>
> mfG Spess

Wo ist der unterschied zu meiner Version mit:
1
    ldi      value, 0
2
    out      OCR1AH, value
3
    ldi      temp1, 0xFF
4
    out      OCR1AL, temp1

Wenn ich den Wert in Value anpasse und da reinschreibe sollte das doch 
klappen oder nicht? Also wenn ich per Hand "0" reinmache ist die LED 
fast aus, bei 255 voll an... Also wo ist denn mein Fehler?

Und was genau hat es mit der Schreibweise High($8000) und Low($8000) auf 
sich?

Tut mir leid wenn es anstrengend ist, irgendwo muss ich den Anfang 
finden ;-) Danke schonmal für die Hilfe!

von spess53 (Gast)


Lesenswert?

Hi

>Wenn ich den Wert in Value anpasse und da reinschreibe sollte das doch
>klappen oder nicht? Also wenn ich per Hand "0" reinmache ist die LED
>fast aus, bei 255 voll an... Also wo ist denn mein Fehler?

Du hattest nicht genau geschrieben, was nicht funktioniert. Aber so 
passt das schon.

>Und was genau hat es mit der Schreibweise High($8000) und Low($8000) auf
>sich?

Benutzt man um 16-Bit Konstanten aufzuteilen:

High($8000) = $80
 Low($8000) = $00

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.