Archiv verlassen und diese Seite im Standarddesign anzeigen : 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
trickTronic
08.06.2006, 09:58
Hallo,
ich kann dir nur einen c-code (winavr) zur Verfügung stellen:
#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
trickTronic
08.06.2006, 10:24
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
trickTronic
08.06.2006, 10:27
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
trickTronic
08.06.2006, 10:28
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
trickTronic
08.06.2006, 14:58
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
Hab jetzt mal dass geschrieben!
.include <m8535def.inc>
.org 0x0000
rjmp Reset
.org OVF0addr
rjmp michi
.org OC0addr
rjmp PWM
Reset:
ldi R26, 0b00000000
ldi R16, HIGH(RAMEND)
out SPH, R16
ldi R16, LOW(RAMEND)
out SPL, R16
ldi R16, 0b00000001
out TCCR0, R16
ldi R16, 0b00000011
out TIMSK, R16
ldi R17, 1
out OCR0, R17
sei
loop1:
ldi R27, 0b00000001
out DDRA, R27
ldi R16, 0b00000010
out DDRA, R16
rjmp loop1
loop2:
ldi R27, 0b00000001
out DDRA, R27
ldi R16, 0b00000000
out DDRA, R16
rjmp loop2
PWM:
out TCNT0, R26
out OCR0, R17
sei
sbis DDRA, 1
rcall loop1
rcall loop2
michi:
reti
mfg
Michael
trickTronic
08.06.2006, 16:53
Ich habs zwar nicht getestet aber so müsste theoretisch pin1 von Port a pwm-mäßg bei 50% toggeln.
.include <m8535def.inc>
.org 0x0000
rjmp init
.org OVF0addr
rjmp ovf
.org OC0addr
rjmp ocr
init:
ldi R26, 0b00000000
ldi R16, HIGH(RAMEND)
out SPH, R16
ldi R16, LOW(RAMEND)
out SPL, R16
ldi R16, 0x7b
out TCCR0, R16
ldi R16, 0x03
out TIMSK, R16
ldi R17, 0x7f
out OCR0, R17
ldi DDRA, 0x01
sei
mainloop:
rjmp mainloop
ovf:
ldi r16, 0x01
out PORTA, r16
reti
ocr:
ldi r16, 0x00
out PORTA, r16
reti
MFG,
Alex
Hmm ... leicht umständlicher Code.
BTW: Mal als Tip: Benutz mal die Suchfunktion !!!
Rauskommen könnte da z.B. dieses als Ergebniss: klick mich !! (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=18866&highlight=software+pwm)
Dieses sollte als Denkansatz durchaus ausreichen, zumal ich mich weigere jemandem den kompletten Code zu schreiben.
Grüße,
da Hanni.
neinnein brauchst nicht den code schreiben. Will eh selber rausbekommen.
Brauche nur anhaltspunkte!
mfg
Michael
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.