-
SOFTWARE-PWM
Hallo leute
Mal ne frage!
Hab schon ein paar sachen gelesen über software PWM, aber komm da nicht so ganz mit! Ich meine ab welcher frezuenz ist die led hell und ab welcher frequenz ist die led gedimmt, also dass man halt nicht dass flimmern sieht??
Bitte um Rückantwort wWIE ICH DASS AM BESTEN ANSTELLE in ASSEMBLER!
Also einen vorschlag hätte ich, mit TIMER?
NAJA BITTE UM HILFE
MFG
Michael
-
Hallo,
ich kann dir nur einen c-code (winavr) zur Verfügung stellen:
Code:
#include <avr\io.h>
#include <avr\interrupt.h>
void PwmInit(void) {
gTimerCounter0 = 0;
sPwmMode = pwmMode;
/* Timer/Counter 0 initialization
* Clock source: System Clock / 1024
* Clock Mode: Fast PWM
* Clock value:
* 5,46ms, 12MHz -> prescale 256 (Frequenz ca. 183Hz)
* duty cycle 50% -> OCR0 127
*/
TCCR0 = 0
| BIT_WGM00 | BIT_WGM01 /* Fast PWM */
| BIT_COM00 | BIT_COM01 /* Set OC0 on Compare Match, Clear OC 0 at Top */
| BIT_CS02; /* N = 256 */
TIMSK |= (0
| BIT_TOIE0 /* Output Compare Interrupt Enable */
| BIT_OCIE0); /* Overflow Interrupt Enable */
OCR0 = 0x7f; /* 50% */
TCNT0 = 0;
}
ISR(TIMER0_COMP_vect) {
/* todo: Ausgänge ausschalten */
}
ISR(TIMER0_OVF_vect) {
/* todo: Ausgänge setzen */
}
void BrightnessSet(unsigned char brightness) {
OCR0 = brightness;
}
Der Prescaler für den Timer wurde mit 12MHz (für den Atmega16) bestimmt.
Ich habe damit eine Frequenz von ca. 183Hz, das reicht um die LEDs durchgängig leuchten zu sehen.
Die Helligkeit kann in 256 Schritten eingestellt werden, defaultmäßig liegt sie in diesem Beispiel bei 50%.
LG,
Alex
-
Brauche es aber für ATMEGA8535 mit 4MHZ!
Bitte nicht in C sondern in assembler!
danke
michael
-
tja.
ich wollt dir nur einen Anhaltspunkt geben...
Lt. Datenblatt des atmega8535 funktioniierts genau gleich.
Die Frequenz berechnet sich so:
f(pwm) = f(io)/(256*N) = 4000000/(256*N) =
-
aber habe keine ahnung wie ich dass anstellen soll? Soll ich mit interrupt arbeiten im Timer??
MFG
Michael
-
sorry, falschen button erwischt...
15625/N
Wenn du eine Frequenz um die 150Hz haben willst ->
N = 15625/150 = 104.
Da du als N nur 1,8,64,256,1024 auswählen kannst nimm z.B. einfach (wie in meinem Code) 256 und es kommen 61Hz raus. Bei 64 ist es das 4-fache!
MFG, Alex
-
Mein Beispiel benutzt den Interrupt.
Aber assemblieren tu ich den code nicht.... warum willst du keinen c-compiler benutzen? ist doch viel einfacher...
-
Kann ich dass so machen??
.include <m8535def.inc>
.org 0x0000
rjmp Start
.org OVF0addr
rjmp ein
Start:
ldi R16, High(RAMEND)
out SPH, R16
ldi R16, LOW(RAMEND)
out SPL, R16
ldi R16, 0b00000001
out TCCR0, R16
out TIMSK, R16
sei
aus:
;Code für ausschalten
rjmp loop
ein:
;Code für ausschalten
reti
bitte um rückantowrt
MFg
Michi
-
Ich kapier dass noch immer nicht mit den Timer eine PWM hinzubekommen!
BITTE HELFEN!!
MFG
Michael
-
TCCR0:
Fast PWM: WGM01=1, WGM00=1
Set OC01 on Compare Match, Clear OC0 at top: COM01=1, COM00=1
Clock(IO)/64(from Prescaler). CS02=0; CS01=1, CS00=1
FOC0: inactive at fast-pwm-mode
Ergibt:
TCCR0 = Bit 6 5 4 3 1 0 = 0x7b;
TIMSK:
Interrupt enable: Output Compare und Overflow Flag, Bits 0 und 1
TIMSK |= 0x03; (| nur wenn andere Timer auch verwendet werden)
TCNT = 0; -> TimerCoutner auf 0 setzen.
OCR0 -> bestimmt Helligkeit.
Anhand des Datenblatts (Abschnitt 8-Bit-Timer-Counter0 with PWM, Figure32. Timing Diagram) zählt der Counter mit dem Prescaler immer hoch. Wenn der Wert in OCR erreicht ist wird der OCR-Interrupt(output compare) ausgelöst, kommt der Zähler oben an wird der TOV-Interrupt (Timer overflow) ausgelöst und der Zähler beginnt wieder bei 0.
Die Perioden des Timers zum Überlauf sind immer gleich lang, die Dauer zwischen Overflow und OCR beträgt somit [t(ges)*256/OCR].
Das sollte genug sein. Noch Fragen?
Alex