www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega88 PWM Tastverhältnis/DutyCycle bestimmen


Autor: Felix Krauss (felix_xyz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
vor dem Problem erst einmal die Beschreibung des Aufbaus:
Ich versuche einen Wert über eine PWM Signal bzw den DutyCycle von einem 
Atmega88 zu einem anderen zu übertragen.
Genutzt werden sollen nur >20PWM% und <80PWM%. Also eigentlich ganz 
simpel. Die Atmegas laufen beide mit einem 8Mhz Quarz. Meine Vorstellung 
war nun eine Frequenz (100Hz-300Hz) zu nehmen und im Sende-Atmega 
einfach den DutyCycle zu verändern. Dieser soll dann am Empfangs-Atmega 
über PinB0 / ICP1 ausgemessen werden und dann diesem „stabil“ zur 
Verfügung stehen.
Mein Problem ist nun, dass der DutyCycle nicht schwanken darf. Doch 
leider schwankt das ermittelte Signal manchmal und manchmal nicht…
Meine Frage an euch ist nun:
Habe ich beim Auswerten des PWM Signals einen Fehler gemacht?  Dass der 
Fehler beim erzeugen vom PWM Signal liegt kann ausgeschlossen werden. 
Ich habe bereits eine stabile PWM-Quelle als Sender benutzt. Mit 
demselben schwankenden Ergebnis :(

Hoffe es kann mir jemand helfen!
Gruß Felix

Zum Auswerten verwende ich folgenden Code:

unsigned long DC_Array[11]={0,0,0,0,0,0,0,0,0,0};
unsigned char PWMOK=1;
unsigned long ic_zp_A1 = 0;
unsigned long ic_zp_B   = 0;
unsigned long ic_zp_A2, ISR_A1, ISR_A2, ISR_B;
unsigned long Ziel=0;
unsigned long DutyCycle;

int main (void)
{
TCCR1B |= (1<<ICES1)  | (0<<CS11) | (1<<CS10) |(1<<ICNC1);
TIMSK1 |= (1<<ICIE1);
sei();

while(1)      //Endlosschleife
  {
    ic_zp_A1=ISR_A1;//-ISR_A2;
    ic_zp_B=ISR_B;//-ISR_A2;
    if((ic_zp_A1>ic_zp_B))  //Komplett ungültige Werte filtern
    {
      for (x=9;x>0;x--) //immer 10 Werte schieben und vergleichen
      {
      DC_Array[x]=DC_Array[x-1];
      }
      DC_Array[0]=((ic_zp_B*10000)/ic_zp_A1);
      for (x=9;x>0;x--)
      {
        if (DC_Array[x]==DC_Array[x-1])
          {PWMOK=1;}
        else
          {PWMOK=0;}
      }
      //Nur wenn 10Messungen denselben Wert ergeben haben
if (PWMOK==1)
{
        DutyCycle0=DC_Array[0];
        DutyCycle=DutyCycle0/39;
        UpdateDisplay=0;
        if ((DutyCycle>200)||(DutyCycle<50))
        {
          Unterprogramm();
        }
        else
        {
        }
      }
    }
}
}
//########################### ISR Routine ###########################
ISR (TIMER1_CAPT_vect)
{
cli();
  if (TCCR1B & _BV(ICES1))
  {
    ISR_A1 = ICR1;
    TCNT1=0;
    TCCR1B &=~(1<<ICES1);//auf fallende Flanke Triggern
  }
  else
  {
    ISR_B = ICR1;
    TCCR1B |= (1<<ICES1);//auf steigende Flanke triggern
  }
sei();
}

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.