Forum: Mikrocontroller und Digitale Elektronik Timer1 Register High Bytes nicht beschreibbar?


von derOJ (Gast)


Lesenswert?

1
        ldi r16, 0x7A
2
  ldi r17, 0x11
3
  sts OCR1AH, r16
4
  sts OCR1AL, r17
5
6
  ldi r16, 0xF4
7
  ldi r17, 0x23
8
  sts ICR1H, r16
9
  sts ICR1L, r17

Mahlzeit!
Ich habe ein Problem mit dem ATMega328P (Arduino Nano V3.0 Board)

Und zwar habe ich anscheinend keinen Zugriff auf die obigen 
High-Register.

Der Timer1 ist auf FastPWM Mode 14 eingestellt.
Mit ICR1 als Top und OCR1A als Compare Register.
Nur leider haben Änderungen in den High Bytes keinerlei auswirkungen auf 
Frequenz und/oder Tastverhältnis.
Ich arbeite mit 16MHz und wollte mit Prescaler 256 eine Periode von ca 
1sek erstellen.
TOP/ICR1 = 62499
Compare/OCR1A = 62499/2

Ich habe zwar ein Tasverhältnis von 50%, durch die LOW Bytes (0x23 und 
0x11), jedoch mit viel zu hoher Frequenz.
Habe auch mal extreme Werte für die High Bytes benutzt um einen Effekt 
sehen zu können, aber egal ob 0x00 oder 0xFF, da ändert sich absolut nix 
am Ausgang.
Woran kann das liegen?

von Jürgen II (Gast)


Lesenswert?

derOJ schrieb:
> Woran kann das liegen?

Wenns hier nicht liegt, in dem nicht gezeigten Code. Mein Ratetipp: 
Prescaler falsch eingestellt.

von Jürgen II (Gast)


Lesenswert?

Jürgen II schrieb:
> derOJ schrieb:
>> Woran kann das liegen?
>
> Wenns hier nicht liegt, in dem nicht gezeigten Code. Mein Ratetipp:
> Prescaler falsch eingestellt.

... bzw. WGM12 WGM13 beim Einstellen von Prescaler überschrieben.

von Hannes L. (hannes)


Lesenswert?

Jürgen II schrieb:
> WGM12 WGM13 beim Einstellen von Prescaler überschrieben.

Oder übersehen, dass die WGMs nicht alle im selben Register liegen?

...

von derOJ (Gast)


Lesenswert?

Danke, dass man sich meiner annimmt :-)

Hier der komplette Code.
Vielleicht suche ich wirklich an der falschen Stelle?
1
  .include "m328Pdef.inc" 
2
3
 .org 0x000 rjmp RESET
4
 .org 0x002 rjmp EXT_INT0
5
6
7
 RESET:
8
  ldi r16, HIGH(RAMEND)
9
  out SPH, r16
10
  ldi r16, LOW(RAMEND)
11
  out SPL, r16
12
13
  ldi XH, HIGH(EICRA)
14
  ldi XL, LOW(EICRA)
15
  ldi r16, (1<<ISC01) | (1<<ISC00)    ;ext INT0 rising edge
16
  st X, r16
17
18
  
19
  ;ldi r16, (1<<INT0)            ;ext INT0 enable
20
  ;out EIMSK, r16
21
22
  ldi r16, 0b11110011      ;PORTD3, PORTD2 als Eingang
23
  out DDRD, r16
24
  ldi r16, 0b11111011      ;Alle Ausgänge HIGH, PD2 ohne Pullup
25
  out PORTD, r16
26
27
  ldi r16, 0b11111111
28
  out DDRB, r16
29
  ldi r16, 0b11011111
30
  out PORTB, r16                    ;PB1 OC1A als Ausgang für PWM
31
32
  ldi r16, (1<<COM1A1) | (0<<COM1A0) | (1<<WGM11)   ;fast PWM / clear on compare
33
  sts TCCR1A, r16
34
35
  ldi r16, (1<<WGM13) | (1<<WGM12)
36
  sts TCCR1B, r16
37
38
  ldi r16, 0x7A
39
  ldi r17, 0x11
40
  sts OCR1AH, r16
41
  sts OCR1AL, r17
42
43
  ldi r16, 0xF4
44
  ldi r17, 0x23
45
  sts ICR1H, r16
46
  sts ICR1L, r17
47
48
  ;sei          ;Interrupts global
49
  
50
  ldi r16, (1<<CS12)           ; Timer1 starten mit Prescaler 256 für 1 Hz PWM
51
  sts TCCR1B, r16
52
  
53
  
54
  main:
55
56
  rjmp main

von Tipp (Gast)


Lesenswert?

Hallo,

erstmal die Interrupts ausschalten, Register ändern, Interrupts 
einschalten.
Die Trennung zwischen High und Low Byte brauchste nicht machen. Macht 
der Compiler für dich. Du kannst das ganze Register ansprechen.
Und ganz wichtig, am Anfang alle Timer Register Nullen. Nur dann geht 
man sicher das auch nur die Bits drin stehen die man selbst gesetzt hat.

von derOJ (Gast)


Lesenswert?

Vielen Dank.

Aber:
Interrupts sind doch aus...

Und wenn ich "sts ICR1, 0xF423" schreibe meldet der Compiler, dass diese 
Variable nicht bekannt ist. Ist auch in der .inc nicht definiert

von derOJ (Gast)


Lesenswert?

Gerade nochmal ausprobiert.
direkt nach der Stackpointer Initialisierung einen "cli" gemacht,
alle benutzten Register auf Null gesetzt mit
clr r16
sts Register , r16

keine Änderung.... :-(

von H.Joachim S. (crazyhorse)


Lesenswert?

du schreibst 2x stumpf nach TCCR1B...

0000 004A TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | 
(1<<WGM11) | (0<<WGM10);
00005f e8e2        LDI  R30,LOW(130)
000060 93e0 0080   STS  128,R30
                 ; 0000 004B TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) 
| (1<<WGM12) | (1<<CS12) | (0<<CS11) | (0<<CS10);
000062 e1ec        LDI  R30,LOW(28)
000063 93e0 0081   STS  129,R30

von Jürgen II (Gast)


Lesenswert?

derOJ schrieb:
>   ldi r16, (1<<CS12)           ; Timer1 starten mit Prescaler 256 für 1
>   sts TCCR1B, r16

Hier überschreibst du dir deine WGM12, WGM13 Bits, die auch im TCCR1B 
stehen mit 0.

von Oliver S. (oliverso)


Lesenswert?

derOJ schrieb:
> ldi r16, (1<<CS12)           ; Timer1 starten mit Prescaler 256 für 1
> sts TCCR1B, r16

Hm...

Oliver

von derOJ (Gast)


Lesenswert?

Wie blööööd :D

Danke. Genau das war der Fehler!
Dachte das wär direkt ne "Oder Operation"
Lese jetz zuerst das/die Register und mach selbst en logisches Oder und 
funktioniert natürlich! :-)

Besten Dank

von Axel S. (a-za-z0-9)


Lesenswert?

Tipp schrieb:
> Die Trennung zwischen High und Low Byte brauchste nicht machen. Macht
> der Compiler für dich.

Was denn für ein Compiler? Das ist Assembler-Code, kein C.

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.