Forum: Mikrocontroller und Digitale Elektronik PWM mit Interrupt auf mehrere Ausgänge (je nach Auswahl) (Atmega8)


von Tobi (Gast)


Lesenswert?

Hallo,

ich such gerne nach Lösungen aber ich komme gerade nicht weiter. Ich 
möchte gerne an 3 Pins das PWMsignal ausgeben je nachdem ob am 
entsprechenden zugeordneten Eingangspin ein high oder low anliegt. Für 
mein Beispiel möchte ich an PB4 das PWM-Signal ausgeben solange der 
Eingang PC2 auf high ist. Sobald ich den Eingang PC2 auf low ziehe soll 
am Ausgang kein Signal (low) anliegen.
Die Erzeugung des PWM-Signals funktioniert bestens, sobald ich die 
Abfrage des entsprechende Pin (im Bsp. PC2) einbaue zeigt sich folgendes 
Fehlerbild: Ist der Pin PC2 auf high wir das PWM-Signal ausgegeben, 
sobald ich PC2 auf low ziehe liegt an Ausgang PB4 ein high-Signal an. 
Warum?
Hier die entsprechenden Codezeilen, den Fehler vermute ich in der ISR 
(TIMER2_OVF_vect)-Routine:
1
int main(void)
2
{
3
        init_Timer_2();
4
  sei();
5
  
6
    while(1)
7
    {
8
    
9
        //TODO:: Please write your application code 
10
    }
11
}
12
13
ISR (TIMER2_COMP_vect)
14
{
15
  DDRB &= ~(1<<PB4);
16
}
17
18
ISR (TIMER2_OVF_vect)
19
{  
20
  if (PINC & (1<<PC2))
21
  {
22
    DDRB |= (1<<PB4);
23
  }
24
  else
25
  {
26
    DDRB &= ~(1<<PB4);
27
  }
28
}
29
30
void init_Timer_2(void)
31
{
32
  DDRB |= (1<<PB3); //Ausgang PWM-Signal
33
  DDRB |= (1<<PB4); //Ausgang PWM-Signal 
34
  TCCR2 |= (1<<WGM20)|(1<<WGM21); // Fast PWM
35
  TCCR2 |= (1<<COM21); //Set Pin on Button clear at match
36
  TCCR2 |= (1<<CS20); 
37
  TIMSK |= (1<<TOV2) | (1<<OCF2); //Interrupt Compare Match und Overflow an
38
  OCR2 = 127;
39
40
  // Eingänge zur Abfrage des Statues zwecks PWMdurchschaltung
41
  DDRC &= ~(1<<PC2);
42
  PORTC |= (1<<PC2); //interne Pullups an
43
}

von Ingo L. (corrtexx)


Lesenswert?

Tobi schrieb:
> Ist der Pin PC2 auf high wir das PWM-Signal ausgegeben,
> sobald ich PC2 auf low ziehe liegt an Ausgang PB4 ein high-Signal an.
> Warum?
Wenn du den PWM-Ausgang als Eingang umschaltest, hast du plötzlich einen 
offenen Eingang, der beliebigen Pegel annehmen kann, meist aber "H". Von 
daher, lieber die PWM-abtrennen (über die COM-Bits).
1
TCCR2 &= ~(1<<COM21);

: Bearbeitet durch User
von Tobi (Gast)


Lesenswert?

Ingo L. schrieb:
> Wenn du den PWM-Ausgang als Eingang umschaltest,

Dies hat mich stutzig gemacht (Manchmal wird man bei der ganzen Suche 
einfach nur betriebsblind). Ich will meinen Ausgang eigentlich garnicht 
umschalten. Habe es jetzt so geändert:
1
ISR (TIMER2_COMP_vect)
2
{
3
4
  PORTB &= ~(1<<PB4);
5
6
7
}
8
9
ISR (TIMER2_OVF_vect)
10
{  
11
  if (PINC & (1<<PC2))
12
  {
13
    PORTB |= (1<<PB4);
14
  }
15
  else
16
  {
17
    PORTB &= ~(1<<PB4);
18
  }
19
}

Jetzt funktioniert es wie gewünscht. Nochmal herzlichen Dank.

von Ingo L. (corrtexx)


Lesenswert?

Tobi schrieb:
> Jetzt funktioniert es wie gewünscht. Nochmal herzlichen Dank.
Aber das deckt sich nicht mit deiner Funktionsbeschreibung. Der Zugriff 
auf das PORT-Register dürfte eigentlich keine Auswirkung auf die PWM 
selbst haben. So wie es derzeit ist, übernimmst nur nur den Pinstatus 
von PC2 auf PB4. Oder was übersehe ich da?

: Bearbeitet durch User
von Tobi (Gast)


Angehängte Dateien:

Lesenswert?

Ingo L. schrieb:
> So wie es derzeit ist, übernimmst nur nur den Pinstatus von PC2 auf PB4.

Ja, aber immer nur zu dem Zeitpunkt wenn der overflow-interrupt des 
Timers auslöst. Sobald der comparematch-Interrupt ausgelöst wird schalte 
ich immer auf low.(Siehe Timerdiagramm im Anhang) So verknüpfe ich das 
PWM signal mit dem Status an PC2. Evtl. hab ich mich auch bei meiner 
Beschreibung etwas unklar ausgedrückt. Eigentlich will ich das 
PWM-Signal mit dem Status an PC2 mit einem und-Funktion verknüpfen.

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.