Forum: Mikrocontroller und Digitale Elektronik pwm-soft


von Seb (Gast)


Lesenswert?

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.

von Daniel M. (usul27)


Lesenswert?

Ist im Prinzip doch ganz einfach:

loop (
 Port einschalten
 warten
 Port ausschalten
 warten
)

von Seb (Gast)


Lesenswert?

Danke,
kann man damit ein Led-leuchtstärke steuern ?

von Daniel M. (usul27)


Lesenswert?

Natürlich kann man das. Und zwar indem man die Wartezeiten in der 
Dunkel- und Hell-Phase entsprechend variiert.

von Exodus155 (Gast)


Lesenswert?

Machs mitn timer! guck mal ins datenblatt TCNT0 oder so da wird die PWM 
erklärt! aja welchen µC verwendest du denn?


MFG
Mike

von Exodus155 (Gast)


Lesenswert?

machs ma so(habs mitn ATMEGA8535 gemacht):

.include <m8535def.inc>


;Ausgang schalten:

ldi R16, 0b00001000

out DDRB, R16

ldi R17, 10 ;<--------------NUR diesen Wert verändern und STAUNEN ;-)

out OCR0, R17

;Eingang initialisieren

ldi R16, 0xff

out PINA, R16

;Stack init

ldi R16, HIGH(RAMEND)

  out SPH, R16

ldi R16, LOW(RAMEND)

  out SPL, R16

;TIMER0 init

ldi R16, 0b01110001

out TCCR0, R16



loop:

rjmp loop




P.s.: WELCHEN µC hast denn?



MFG
Mike


von johnny.m (Gast)


Lesenswert?

@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.

von johnny.m (Gast)


Lesenswert?

...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.

von Exodus155 (Gast)


Lesenswert?

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






von johnny.m (Gast)


Lesenswert?

@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.

von Exodus155 (Gast)


Lesenswert?

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


von Rolf Magnus (Gast)


Lesenswert?

> 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.

von johnny.m (Gast)


Lesenswert?

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.

von Seb (Gast)


Lesenswert?

danke Leute,ich versuch hier einmal mit Atmega8 und ATTINY2313,
ich probiere 'es heute ....
danke

von Karl heinz B. (kbucheg)


Lesenswert?

> 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

von Michael M. (irosenhag)


Lesenswert?

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);

}

von Karl heinz B. (kbucheg)


Lesenswert?

> 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.

von Michael M. (irosenhag)


Lesenswert?

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

von Michael M. (irosenhag)


Lesenswert?

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.

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.