8051er PWM

S

Simone Winkler

Guest
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 */
 
In article <oS%Tc.13827$N77.581661@news.xtra.co.nz>,
"Simone Winkler" <simone.winkler@gmx.at> writes:
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.
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).

Wie könnte ich das, falls es nicht geht, noch machen? Habe einen Timer
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
 
Hallo Simone,

ich programmiere gerade einen P87C552 (8051er core). Ich möchte ein
Das Philips Teil? Du tust dir n EPROM/OTP heute noch an? ;)

PWM-Signal erzeugen und ein zweites PWM-Signal, das sozusagen um eine
bestimmte Delay-Zeit versetzt zum ersten PWM-Signal startet.
Also sowas?

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


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


Wie könnte ich das, falls es nicht geht, noch machen? Habe einen Timer
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.

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;
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
 
Hallo Simone,

Oder ist die Startzeit des PWM-Signals immer dieselbe?
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.

Komischerweise muß ich für overflow_count 16 statt 15 eintragen, damit
die Frequenz stimmt
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
 

Welcome to EDABoard.com

Sponsor

Back
Top