Sehr geehrtes Forum,
mal wieder habe ich ein Problem, und zwar möchte ich gerne
die PWM Kanäle OC1A und OC1B nutzen.
Dazu habe ich mir das Tutorial
https://www.mikrocontroller.net/articles/AVR-Tutorial:_PWM#Fast_PWM
durchgelesen, ebenso wie den Abschnitt im Datasheet.
Ich habe eine LED an PB0 angeschlossen, um zu sehen wie stark die LED
normal leuchtet, sowie eine zweite LED mit einem Kabel, das mit PB1
verbunden ist, damit ich einen Helligkeitsunterschied feststellen kann.
Dieses Kabel ist ein Flexwire auf einem Breadboard, welches ich dann zum
Vergleich auch an PB2 stecken kann.
PB1 ist ja der PWM Kanal OC1A, und PB2 ist ja der PWM Kanal OC1B.
Das mit OC1A funktioniert, die LED leuchtet, aber eben gedimmt.
Das mit OC1B funktioniert nicht, die LED ist aus.
Sogar wenn ich den Code zum Setzen von OCR1AH/L auskommentierte,
leuchtet die LED am Ausgang von PB01 weiter, und zwar in dieser
Dimmstufe, und am Ausgang PB02 passiert weiterhin nichts.
Wie kann das sein?
1
.include "m88def.inc"
2
3
/*
4
Eine LED soll gedimmt werden
5
*/
6
7
.CSEG
8
.DEF temp1 = R17
9
10
// Stackpointer initialisieren
11
LDI R16, low(RAMEND)
12
OUT SPL, R16
13
LDI R16, high(RAMEND)
14
OUT SPH, R16
15
16
// Richtung der IO Ports definieren
17
LDI R16, 0b11111111 // 1=Output, 0=Input
18
OUT DDRB, R16
19
SBI PORTB, PB0
20
21
//PWM_INIT:
22
// Einstellen des PWM, Timer mit CPU Takt eingestellt, WG-Modus 14
23
LDI R16, (1<<COM1A1) | (1<<WGM11)
24
STS TCCR1A, R16
25
26
LDI R16, (1<<WGM13) | (1<<WGM12) | (1<<CS00)
27
STS TCCR1B, R16
28
29
// Einstellen des TOP Wertes
30
LDI R16, 0
31
STS ICR1H, R16
32
33
LDI R16, 200
34
STS ICR1L, R16
35
36
// Einstellen des Compare Wertes und wählen des Kanals
37
LDI R16, 0
38
STS OCR1AH, R16
39
40
LDI R16, 10
41
STS OCR1AL, R16
42
43
LDI R16, 0
44
STS OCR1BH, R16
45
46
LDI R16, 50
47
STS OCR1BL, R16
48
49
//RET
50
51
// Main Schleife
52
53
MAIN:
54
RJMP MAIN
Was ich des Weiteren fragen wollte, weil das nicht im Datasheet steht
und auch nicht im Tut: Kann man dann zum Nutzen der anderen beiden 16
Bit PWM Kanäle OC2A und OC2B, an den Pins PB3 und PD3, einfach dieselben
Register, einfach mit einer "2" notiert, sprich TCCR2A, TCCR2B,
ICR2(H/L) und OCR2(A/B)(H/L), verwenden?
Danke für eine Antwort,
m.f.G.: Developer_X
Ah!
Danke sehr! Jetzt klappt es.
War ja wieder klar dass ich das übersehe xd.
Hast du auch eine Antwort auf meine Frage:
A. B. schrieb:> Was ich des Weiteren fragen wollte, weil das nicht im Datasheet steht> und auch nicht im Tut: Kann man dann zum Nutzen der anderen beiden 16> Bit PWM Kanäle OC2A und OC2B, an den Pins PB3 und PD3, einfach dieselben> Register, einfach mit einer "2" notiert, sprich TCCR2A, TCCR2B,> ICR2(H/L) und OCR2(A/B)(H/L), verwenden?
Denn einfach ne zwei schreiben funktioniert definitiv nicht.
Danke für eine Antwort,
m.f.G.: Developer_X
Hi
Ich weiß nicht, ob ich dich richtig verstanden habe: Timer2 ist ein
8-Bit Timer. Da gibt es nur die Register OCR2B, OCR2A, TCNT2, TCCR2B und
TCCR2A.
MfG spess
Also im Datenblatt gibt es Kapitel 15, da geht es um den 8Bit Timer mit
Erklärung wie man die PWM Kanäle OC0A und OC0B verwendet, wenn ich das
richtig verstanden habe. Und hier kann man, im Gegensatz zu den OC1A und
OC1B leider nur über interrupts eine PWM erzeugen, denn man kann hier
nur den TOP Wert, allerdings keinen COMPARE Wert setzen.
Kapitel 16 behandelt ja die OC1A und OC1B.
Worum es mir geht ist, wie man die Kanäle OC2A und OC2B nutzen kann.
...
Ah, Kapitel 18, sehe ich gerade.
Ich habe das schonmal mit den Kanälen OC0A und OC0B versucht, aber
leider ohne Erfolg:
1
.include "m88def.inc"
2
3
/*
4
Eine LED soll gedimmt werden
5
*/
6
7
.CSEG
8
.DEF temp1 = R17
9
10
// Stackpointer initialisieren
11
LDI R16, low(RAMEND)
12
OUT SPL, R16
13
LDI R16, high(RAMEND)
14
OUT SPH, R16
15
16
// Richtung der IO Ports definieren
17
LDI R16, 0b11111111 // 1=Output, 0=Input
18
OUT DDRB, R16
19
OUT DDRD, R16
20
SBI PORTB, PB0
21
22
23
//PWM_INIT_CHANNELS_0
24
// Einstellen des PWM, Timer mit CPU Takt eingestellt, WG-Modus 3
// Einstellen des Compare Wertes und wählen des Kanals
32
LDI R16, 10
33
STS OCR0A, R16
34
35
LDI R16, 50
36
STS OCR0B, R16
37
38
39
// Main Schleife
40
41
MAIN:
42
RJMP MAIN
Ich hab die LEDs an PD5 und PD6 gesteckt, und keine von beiden leuchtet.
Ich gehe mit meinem Code davon aus, dass der Counter bei dem Compare
Wert wechselt, und der Top Wert bei PWM Kanälen basierend auf den 8 Bit
Timern immer 255 beträgt.
Was mache ich hier falsch?
Ah ich sehe gerade, dass das mit 8 Bit Timern nur über Interrupts geht,
oder liege ich da falsch?
In allen Modes of Operation in Kapitel 15.7 scheint es immer nur darum
zu gehen, dass man entweder Flags überwacht oder Interrupts.
Oder?
Keiner dieser Modi funktioniert wie die viel einfacher handhabbaren auf
Basis der 16 Bit Timer.
Hi
Die vorhandenen PWM-Modi funktionieren bei den 8-Bit-Timern genau so wie
bei den 16-Bit-Timern. Wesentlicher Unterschied ist, das da kein
IC-Register existiert mit dem man den Top-Wert einstellen kann. Entweder
man benutzt den festen Wert $FF als Top-Wert oder man opfert Compare
Register A für einen eibstellbaren Top-Wert.
MfG Spess
Ja ok, aber wie siehts aus mit dem invertieren des Signals, muss man das
selbst machen, oder macht er das dann, weil mein Code liefert solch ein
Ergebnis momentan leider nicht :( ob wohl ich FastPWM ausgewählt habe.
Ich habe jetzt folgende Einestellung:
COM0A0 und COM0B0 gesetzt.
Ich will ja, dass es toggelt, jetzt steht in der Tabelle,
dass er toggelt, wenn WGM02 aktiviert ist, wir reden ja von der Tabelle
des FASTPWM, und dann haben wir das problem, dass wir den Modus 7
auswählen, bei welchem TOP OCR0A gleicht, und es nie zum Toggeln kommt.
Mit welcher Einstellungen ist es denn möglich mein Vorhaben zu
realisieren?
Hi
>Ich will ja, dass es toggelt, ...
Sicher? Das würde aus OC0A eine CTC, aber keine PWM machen. Zwei Fast
PWM Ausgänge bekommst du nur im Mode3
MfG Spess
Also:
Ich stelle Modus 3 ein, schau dann in die Tabelle zur Setzung von
COM0AX-Bits, die für den Modus FASTPWM, und dort steht, S101, letzte
Tabelle, dritte Zeile, 1,0, Clear OC0A on compare match, set OC0A at
BOTTOM,
(non-inverting mode).
Das habe ich alles eingestellt, und trotzdem ist nichts an der LED zu
sehen.
1
.include "m88def.inc"
2
3
/*
4
Eine LED soll gedimmt werden
5
*/
6
7
.CSEG
8
.DEF temp1 = R17
9
10
// Stackpointer initialisieren
11
LDI R16, low(RAMEND)
12
OUT SPL, R16
13
LDI R16, high(RAMEND)
14
OUT SPH, R16
15
16
// Richtung der IO Ports definieren
17
LDI R16, 0b11111111 // 1=Output, 0=Input
18
OUT DDRB, R16
19
OUT DDRD, R16
20
SBI PORTB, PB0
21
22
//PWM_INIT_CHANNELS_0
23
// Einstellen des PWM, Timer mit CPU Takt eingestellt, WG-Modus 3
Ich bin ganz ehrlich, ich habe das Datasheet jetzt drei viermal gelesen
und alle möglichen Kombintationen probiert, was ist denn nun die
richtige Konfiguration, so komme ich nie drauf, das kostet einfach Zeit
und Nerven, ohne dass dabei etwas rauskommt :(.
Hi
> was ist denn nun die>richtige Konfiguration, so komme ich nie drauf, das kostet einfach Zeit>und Nerven, ohne dass dabei etwas rauskommt :(.
Benutze einfach für die Ausgaben auf die Timerregister out statt sts.
Die liegen nämlich im normalen IO-Bereich.
MfG Spess
Oh man. Schon wieder dieser Fehler, den hab ich erst gemacht^^.
Danke jetzt funktioniert es endlich mal.
Also in Zukunft auch das im Debugger prüfen, ob wirklich alles gesetzt
wird. Ist notiert.
Danke für deine Hilfe!
m.f.G.: Developer_X