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 */
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 */