Hallo,
ich habe mich hier umgeschaut,leider könnte ich nicht viel verstehen,
brauche bitte mehr literatur zu pwm-soft,oder ein beispiel : erzeugung
von pwm aus eine Port - PD2. mit kommentar wenn es nicht zuviel ist.
Danke Leute.
@Exodus:
Schau mal in den Betreff! Er will eine Soft-PWM. Was Du da machst ist
eine Hardware-PWM. Außerdem sollten man den Stack Pointer, wenn
überhaupt, dann am Anfang des Programms initialisieren, und nicht
irgendwo mittendrin.
...Ach ja, im Übrigen hat Exodus natürlich recht: Wenn Du Hilfe willst,
dann musst Du schon ein paar mehr Details preisgeben, eben z.B. den
Controllertyp, den Du verwenden willst.
ok dass mitn stack war falsch nur mal schnell schnell geschrieben! ;-)
Weiß nich wie ich dass am besten erklären soll aber ich hab hier ma ne
Zeichnung! vielleicht hilft dir die weiter!
|-----------| |-----------|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
-----| |-------------| |----------------->>>>>>>
-------------------------
100%
In diesem Fall würde die Led 50% leuchten
MFG
Mike
@Exodus:
Das ist ja schön und gut, aber er will immer noch eine Soft-PWM, und das
mit dem Compare-Ausgang, was Du beschreibst ist nach wie vor eine
Hardware-PWM...
Für eine Soft-PWM verwendet man sinnvollerweise den Compare-Interrupt
und den Overflow-Interrupt. Im Prinzip muss man nichts anderes tun, als
jeweils in einem der beiden Interrupt-Handler den oder die gewünschten
Portpin(s) ein- und im jeweils anderen wieder auszuschalten, also genau
das, was bei der Version von Exodus die Hardware ganz alleine macht.
warum sollte er sich dass leben schwer machen, wenns doch einfacher
geht?
Naja egal!;-)
Hast du kenntnisse in assembler oder C überhaupt?
Mach ma ein paar Angaben µC-controller, programmiersprache usw....
MFG
Mike
> Für eine Soft-PWM verwendet man sinnvollerweise den Compare-Interrupt> und den Overflow-Interrupt.
Das ist dann aber auch keine richtige Software-PWM. Der Unterschied zur
vollständigen Hardware-PWM ist ja nur noch, dass man das Pin-Toggeln in
Software macht. Das Timing wird durch die Hardware erledigt.
Wenn Du ne "echte" Mehrkanal-Soft-PWM machen willst, brauchst Du im
Prinzip für jeden Kanal (Ausgangspin) ein Vergleichs-Register. In diese
Register kommt der gewünschte Wert für jeden einzelnen Ausgang rein. Im
Hintergrund läuft jetzt der Timer leise vor sich hin. Im Programm muss
jetzt zyklisch überprüft werden, ob der Timerwert einen oder mehrere der
Vergleichs-Register überschreitet. Ist das der Fall, dann wird der
jeweils dazugehörige Pin auf Low geschaltet (nichtinvertierende PWM).
Beim Timer-Overflow (sinnvollerweise Interrupt verwenden) werden alle
Pins auf High gesetzt und das ganze Spiel geht von vorne los.
> Wenn Du ne "echte" Mehrkanal-Soft-PWM machen willst, brauchst Du im> Prinzip für jeden Kanal (Ausgangspin) ein Vergleichs-Register.
Die du aber normalerweise nicht im Timer hast.
Ich hab meine Soft-Pwm so gemacht:
Timer in den CTC-Modus (Overflow hat mir zuwenig Fine-Tuning
erlaubt).
Im CTC Interrupt einen PWM-Zähler um 1 hoch und Überlauf
auf 0 bei einem Zählerstand von 64
Für jede LED gibt es einen Wert. Liegt der PWM-Zähler
drunter, wird die LED eingeschaltet, ansonsten wird
ausgeschaltet.
Das reicht, dass ich 64 LED (über Schieberegister) ohne
Flimmern einzeln dimmen kann. Mega8 bei 12 Mhz
Hey,
ich hab gerade auch an einer Software PWM des Atmega8 rumgetestet.
Allerdings ganz ohne Timer, nur mit 2 Zählschleifen.
Ergebnis ist, daß die LED an Port C5 dauerhaft leuchtet....
Kann ich überhaupt eine PWM mittels Zählschleifen realisieren oder sind
die viel zu ungenau?
mfg
Code:
#include <avr/io.h>
#include "iocompat.h"
int compare;
int counter;
void fadein(void)
{
for(compare=0xffff;compare>0;compare--)
{
for(counter=0x00;counter<0xffff;counter++)
{
if (compare<counter)
{
PORTC=0x10;
}
}
PORTC=0x00;
}
}
void fadeout(void)
{
for(compare=0x00;compare<0xffff;compare++)
{
for(counter=0x00;counter<0xffff;counter++)
{
if (compare<counter)
{
PORTC=0x10;
}
}
PORTC=0x00;
}
}
int main (void)
{
DDRC = 0xff;
while(1)
{
fadein();
fadeout();
}
return(0);
}
> for(compare=0xffff;compare>0;compare--)> for(counter=0x00;counter<0xffff;counter++)
Das macht (grob gerechnet) 65000 * 65000 Durchgänge.
Macht 4225000000 Durchgänge. Wenn wir mal annehmen
dass ein Durchlauf durch die Schleifen 10 Takte dauert,
macht das bei 12 Mhz 3520 Sekunden. Ds sind ~58 Minuten
Also nicht ganz eine Stunde. Wenn ein Schleifendurchlauf
10 Takte dauert, was ich bezweifle.
Na ja, ich hatte vorher mit 0xff also 255 ausprobiert und dachte die LED
ist an, weil die Abstände zu klein sind ;)
Aber gerechnet hatte ich nicht, muß ich zugeben.
Ist die PWM denn von der Logik her so realisierbar, oder bin ich total
auf dem Holzweg?
mfg
Ich hab das Programm nochmal durchgeguckt und mir ist folgendes
aufgefallen.
Bei der Initialisierung der Ports:
int main (void)
{
//DDRC = 0b00100000;
DDRC = (1 << DDC5);
PORTC = (0<<PC5);
....
}
Setzt er Pin C5 sofort auf 1. Die nachfolgende Anweisung der 0 wird
anscheinend ignoriert.
Auch die Aufrufe in der Unterfunktion zum einblenden der LED bewirken
dann scheinbar nichts mehr.
mfg
Edit:
Ah hoppla, jetzt gehts auf einmal ;)
Zwar genau andersrum (LED wird 1 dann langsam auf 0 gedämmt), als ich
gedacht hatte aber immerhin ein Fortschritt.