8051er PWM

Hallo,

ich programmiere gerade einen P87C552 (8051er core). Ich möchte ein PWM-Signal erzeugen und ein zweites PWM-Signal, das sozusagen um eine bestimmte Delay-Zeit versetzt zum ersten PWM-Signal startet. Dazu hab ich versucht, die Register PWM0 und PWM1 zu "versetzten Zeiten" zu schreiben.

Aber irgendwie bekomme ich's nicht hin - im generierten Assembler-Code (ich programmiere in C) sehe ich zwar noch eine Delay-Schleife zwischen den Zuweisungen der beiden Register PWM0 und PWM1, aber in der Ausführung stimmt's dann nicht. Habe allerdings im Datenblatt gelesen, daß die PWM-Register für diesen Chip sofort übernommen werden und nicht erst eine Periode später - also müßte das doch eigentlich gehen, oder? Oder ist die Startzeit des PWM-Signals immer dieselbe?

Wie könnte ich das, falls es nicht geht, noch machen? Habe einen Timer programmiert, aber da der dann irgendwie auch nicht ganz "kohärent" zu dem ersten PWM-Signal war, hab ich lieber versucht, das mit der zweiten PWM zu lösen. Habe an einen externen Interrupt gedacht, aber das ist eine unsaubere Lösung, finde ich (außerdem hab ich wahrscheinlich keinen frei).

Mein Timer sieht so aus: (vielleicht findet irgendwer, wo da der fehler sein könnte - es sollte ein Timer sein, der 300 Hz erzeugt, bei 14,7456MHz Taktrate mit einem Maschinenzyklus von 1/12 der Taktrate). Komischerweise muß ich für overflow_count 16 statt 15 eintragen, damit die Frequenz stimmt, aber irgendwo überlagert sich irgendwas komisch (sodaß im Endeffekt das PWM-Signal mit 300Hz und das Timer-Signal nicht "auf einem Oszibild angesehen werden können, weil man ja nur auf einen Kanal triggert", und ich kann es einfach nicht finden. :( Die PWM-Einstellungen sind übrigens: PWMP=0x5F; PWM0=0x02;

Der Timer:

static unsigned int overflow_count = 16;

void interrupt timer1_ISR (void) { if(overflow_count==0) { P3b.B3=TRUE; overflow_count=16; } overflow_count--; P3b.B3=FALSE; }

void main (void) { /*-------------------------------------- Set Timer1 for 8-bit timer with reload (mode 2). Set the Timer1 Run control bit.

--------------------------------------*/ TMOD = (TMOD & 0x0F) | 0x20; /* Set Mode (8-bit timer with reload) */ TH1 = 0x0; /* Reload TL1 to count 256 clocks */ TL1 = TH1; ET1 = 1; /* Enable Timer 1 Interrupts */ TR1 = 1; /* Start Timer 1 Running */ EA = 1; /* Global Interrupt Enable */

Reply to
Simone Winkler
Loading thread data ...

Hallo Simone,

Das Philips Teil? Du tust dir n EPROM/OTP heute noch an? ;)

Also sowas?

______----_____________----______ ________----_____________----____

Genau, der Controller vergleicht den Counter mit PWM0 und PWM1. Ist der Wert in PWM0/PWM1 groesser als der Counter, gibt er LOW an -PWM0/-PWM1 aus, ist der Wert in PWM0 und PWM1 gleich oder kleiner als der Counter, gibt er HIGH aus. Man kann damit dann 2 PWMs bauen, die die gleiche Frequenz aber ein unterschiedliches Tastverhaeltnis haben. Und sie gehen immer gleichzeitig auf LOW, weil sie beide den Wert in ihrem Register PWMx mit dem gemeinsamen Counter vergleichen.

Muss es der P87C552 sein? 300 Hz sind nicht die Welt, evtl. laesst sich das in einer Interrupt Routine loesen, je nachdem wieviel Rechenleistung du noch frei hast und je nachdem wie weit die 2 Signale verschoben sein muessen.

Also der PWM-Counter zaehlt Modulo 255, also von 0-254. Kannst mal probieren, was passiert, wenn man den Timer1 Reload auf 1 setzt? Aber ich fuerchte, das scheitert dann daran, dass man den PWM-Counter und den Prescaler nicht auslesen kann und damit die Interrupt-PWM nicht damit synchronisieren kann. Jedenfalls wenn ich das Datenblatt richtig verstanden hab :( Ausser, der Counter wird zusammen mit dem Prescaler resettet, wenn man das PWMP Register beschreibt.

Gruss,

Steffen

Reply to
Steffen Koepf

Das geht nicht. Schau dir das Datenblatt z.b. P87C552_3.pdf Seite 22 an. Du hast nämlich nur einen zähler (mir ist auch nichts ins Auge gesprungen womit du diesen Zähler reseten kannst).

Die compareinheit ließe zich zusammen mit T2 für einen unabhängigen PWM mißbrauchen. Wenn es deine Anwendung zulässt könnte man eventuell beide Kanäle damit steuern. Bist du sicher daß sich dein Problem nicht eleganter lösen laßt?

--
MFG Gernot
Reply to
Gernot Fink

Hallo Simone,

Ja, da alle PWMs von einem Timer abhängen, und das PWM-Modul lediglich den Timerwert mit dem PWM-Register vergleicht. Die einzelnen PWMs sind also immer in Phase.

Logisch, da overflow_count gleich nach dem "if" wieder um eins runtergezählt wird. Ein "else" würde das vermeiden. Vielleicht ist deshalb auch das Oszibild unsauber - ohne else wird der Port nur wenige Zyklen später wieder zurückgesetzt. Da der IRQ auch immer etwas versetzt erscheint, gibt das i.V. mit der kurzen Impulszeit Jitter, der das Oszibild verwaschen erscheinen läßt.

Tom

--

------------------------------------------------------
Bitte beachten - AntiSpam-Filter: *.com, *.cn, *.br, *.kr, *.net, *.pl, 
*.ro, *.ru
Reply to
Thomas Langhammer

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.