mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PWM Signal OCR1A auf einen anderen Pin umleiten.


Autor: Eduard Edi (megawatt1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich möchte PWM Signal (µC ATtiny 2313, OCR1A auf PB3) auf PD3 umleiten.
Leider habe ich da ein Problem, die PWM funktioniert am PB3(Pin 15) 
einwandfrei, nur die Weiterleitung funktioniert nicht, die unteren 2 
Zeilen.
Habe schon die (Pin 15, PB3) mit (Pin 14, PB2) verbunden und Pin 14 als 
Eingang konfiguriert, (siehe ganz unten) trotzdem habe ich am Pin7 (PD3) 
kein PWM Signal.
Die Frage, wie kann ich PWM Signal auf einen anderen Pin umleiten ?

Der betreffende Codeausschnitt:
int main(void)
{ 
DDRD |= (1<<PD3);
DDRB |= (1<<PB3);
DDRB &=~ (1 <<PB2)
  
    TCCR1A = 0x83;    // non-inverted PWM on OC1A, 10 Bit Fast PWM
    TCCR1B = 0x08;
    TCCR1B &= ~0x7;         // clear clk setting
    TCCR1B |=4; 
    OCR1A = 0;
  int X=0;
  
  for  (;;) { 

  if (OCR1A<1023) {X++;}
   if ((OCR1A<1023) && (X>10)) {OCR1A=OCR1A++;} 
   if (X==11){X=0;}
       

  if (PINB & (1 << 3)) { PORTD |= (1 << 3);}
  if (!PINB & (1 << 3)) { PORTD &=~ (1 << 3);}
   
    }}

if (PINB & (1 << PB2)) { PORTD |= (1 << 3);}
if (!PINB & (1 << PB2)) { PORTD &=~ (1 << 3);}

Autor: Eduard Edi (megawatt1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mittlerweile bin ich weiter, nachdem ich if durch else ersetzt habe
 if (PINB & (1 << 3)) { PORTD |= (1 << 3);}
    else { PORTD &=~ (1 << 3);}   

funktioniert die Weiterleitung, allerdings sehr ruckelig.
Hat einer Idee wie ich es besser machen kann ?

Autor: Helfer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die Frage, wie kann ich PWM Signal auf einen anderen Pin umleiten ?

Hardware

Mit einer Drahtbrücke? Oder indem man die Weiterleitung vermeidet und 
die per PWM versorgte Hardware an den PWM-Ausgabepin anschliesst.

Wenn man ein PWM Multiplexing oder eine Verteilung des PWM Signals auf 
mehrere Empfänger gleichzeitig machen will, kann man externe 
Hardware-ICs verwenden.

Software

Per Software ist ein Ansatz mit manueller if-Abfrage des PWM Status wie 
oben zu sehen ineffizient. Solltest du noch Luft bei der Taktrate haben, 
erhöhe den Takt des AVR und deine if-Abfragen werden öfter durchgeführt 
und das Ruckeln vermindert sich.

Eine bessere Chance hast du, wenn du dir Interrupts an den 
Umschaltpunkten automatisch geben lässt und in der ISR dann den andere 
I/O-Pin toggelst.

Autor: Eduard Edi (megawatt1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Tipps, da es sich um eine fertige Platine  handelt, sieht 
die  Drahtbrücke nicht so toll aus. Ist wohl aber die beste Lösung. 
Alles andere wird die Abarbeitung verzögern, was den Rest des Programms 
unbrauchbar macht.
Unten sind noch 3 Periode Counter die ganz Zeitkritisch sind.
Ich habe gehofft es gibt eventuell einen Trick den ich nicht kenne..
Ich werde einfach die Drahtbrücke(10k Widerstand)irgendwie auf die 
andere Seite des µC's legen müssen.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Beim ATTiny2313 kann man ein Pin durch einfaches Schreiben einer 1 in 
das Pin-Register togglen.

Toggling the Pin Writing a logic one to PINxn toggles the value of
                 PORTxn,independent on the value of DDRxn.
                 Note that the SBI instruction can be used to toggle
                 one single bit in a port.

MfG Spess

Autor: Eduard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir jetzt einer Code schnipsel schreiben wie ich es lösen könnte ?
Ich möchte PWM Signal (µC ATtiny 2313, OCR1A auf PB3) auf PD3 umleiten.

 if (PINB & (1 << 3)) { PORTD ^= (1 << 3);}

Autor: Helfer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PORTD ^= PINB & (1 << 3);

Autor: Helfer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, nee vergiss das letzte.

Autor: Eduard Edi (megawatt1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die sehr schnelle Antwort, welche Pin bei PORTD getoggelt wird 
?  wo gebe ich Pin3 bei PORTD ein ?

Autor: Eduard Edi (megawatt1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir jemand noch zeigen wie ich die 300Hz Impulse am Eingang PB1, am 
Ausgang PD2 halbieren kann.  Ich habe mir jetzt so gedacht:

  if (PINB & (1 << 1)) { PORTD ^= (1 << 2);}

oder so:

int main(void)
{ 
DDRD |= (1<<PD2);
DDRB &=~ (1 <<PB1)

int i=0;

for  (;;) { 

  if (((PINB & (1 << 1)) && (i<=1)) { i++; }
  if (((PINB & (1 << 1)) && (i==2)) { PORTD |= (1 << 2); i=0; }
  else if ((!(PINB & (1<<1)) && (PINB & (1 << 1))) { PORTD & =~ (1 << 2);} 
}
}
 

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Eduard.
Hier der Link zur meiner Lösung.
http://www.mikrocontroller.net/attachment/103029/test.c
Es gibt bestimmt bessere Beispiele aber es läuft.
Nur achte nicht auf ADC es geht nicht hier im Test-Program.
Du kannst beliebige Ports und Pins in der switch(Port) Anweisung des 
Timers 0 ansprechen.
Sowie eine variable Pulsbreite über den Register OCR0A einstellen.

Autor: Eduard Edi (megawatt1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Daniel, meinst Du so kann es funktionieren ?
// Port 
void Port_Init()
{
  DDRD|=(1<<PD3);
}

#define    Port_Hi    PORTD|=(1<<PD3)
#define    Port_Lo    PORTD&=~(1<<PD3)

void Timer_0 (uint16_t Port)

{  
   OCR1A=OCR1A;        
   if((TCNT1>=0)&&(TCNT1<=OCR1A))
{  
    switch(Port)
    {
      case 0:  Port_Hi; break;
    }
  }else {Port_Lo;}
}
  
int main(void)
{ 
Port_Init();
Timer_0_Init();
uint16_t Res;

//DDRD |= (1<<PD3);
//DDRB |= (1<<PB3);
//DDRB &=~ (1 <<PB2);
  
    TCCR1A = 0x83;    // non-inverted PWM on OC1A, 10 Bit Fast PWM
    TCCR1B = 0x08;
    TCCR1B &= ~0x7;         // clear clk setting
    TCCR1B |=4; 
    OCR1A = 0;
    int X=0;
  
  for  (;;) { 

   if (OCR1A<1023) {X++;}
   if ((OCR1A<1023) && (X>10)) {OCR1A=OCR1A++;} 
   if (X==11){X=0;}
             
Timer_0(Res,0);
}}

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Eduard.
Ich habe die einzelnen EInstellungen von dir in TCCR1A und TCCR1B nicht 
nachgeschaut, sollten stimmen.
Du kannst nicht OCR1A=OCR1A; schreiben, denn es ist dasselbe Register.
Du musst eine Veriable verwenden z.B. OCR1A=Wert; wobei Wert einen 
unsigned int Variable sein muss. Der TCNT1 zählt immer von 0 bis zum 
Vorgabewert im OCR1A.
// Port 
void Port_Init()
{
  DDRD|=(1<<PD3);
}

#define    Port_Hi    PORTD|=(1<<PD3)
#define    Port_Lo    PORTD&=~(1<<PD3)

void Timer_0 (uint16_t Wert, uint8_t Port)

{  
   OCR1A=Wert;        
   if((TCNT1>=0)&&(TCNT1<=OCR1A))
{  
    switch(Port)
    {
      case 0:  Port_Hi; break;
    }
  }else {Port_Lo;}
}
  
int main(void)
{ 
Port_Init();
Timer_0_Init();
uint16_t Res=200;  // Variabler Wert

//DDRD |= (1<<PD3);
//DDRB |= (1<<PB3);
//DDRB &=~ (1 <<PB2);
 
//    Die Angaben müssen mit deinem Controller passen 
    TCCR1A = 0x83;    // non-inverted PWM on OC1A, 10 Bit Fast PWM
    TCCR1B = 0x08;
    TCCR1B &= ~0x7;         // clear clk setting
    TCCR1B |=4; 
//    OCR1A = 0; // weg lassen denn du löschst den Vergleichswert
    
  uint16_t X=0;
  
  for(;;) 
  { 

    for(x; x<1000; x++)  // Nur ein Beispiel
    {
       Timer_0(Res,0);
    }
  }
}
Kompiliert habe ich den oberen Code nicht.
Muss weg.
Du musst schon um genaue Hilfe zu erhalten deinen Controller und 
CPU-Frequenz nennen.
Viel Erfolg.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.