www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AT89C2051 Frequenzmessung


Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten morgen,

Arbeite gerade seit einigen Stunden an einer Frequenzmessung mit dem
AT89C2051 herum, Messfrequenz von 20 bis 400Hz mit einer Auflösung von
0.1Hz. Eingang: Externer Interrupt EX0 @ P3.2
der EX0 Aktiviert mit den Timer1 und lässt ihn hochzählen bis zum 2.ten
Puls der den T1 dann wieder Deaktiviert. Damit die Software diesen wert
dann zu passender zeit mal wieder abholen kann.

Krieg schöne Rechtecke daher aber ab ca. 45Hz flattert mir die Anzeige
davon. Auch die Ausgabe des eigentlichen Eingangssignals auf einem
Sepatatem Ausgang is alles andere als schön, am Oszi sieht man schön
wie die "Antwort" des externen Interrupts hin und her schwankt.

Ideen? Sources? Plan? bei mir herrscht nur noch Blanke verzweiflung,
naja so schlimm is ned aber viel fehlt nimma.

lg Jan

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tja, bei deiner knappen Beschreibung (um es mal vornehm auszudrücken)
kann man nur raten.

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void INTEX0(void) interrupt 0 using 2
{
  RED = ~RED;

  if(new_messure == 0)            // Keine Neue Messung Aktiv!
  {
    TR1 = ~TR1;                  // Timer1 EIN/AUS

    if (TR1 == 0)                // Wurde gerade wieder DeAktiviert!  = 
MESSUNG
FERTIG!!!
    {
      EX0 = 0;                // Externen Interrupt ausschalten!
      pw_high = TH1;
      pw_low = TL1;

      TH1 = 0;
      TL1 = 0;

      new_messure = 1;
    }
  }
  else
    EX0 = 0;                  // ausschalten!
}

void INTTIM1(void) interrupt 3 using 2
{
  TF1 = 0;

  overlap++;
  if (overlap>1)    // Motor Aus!
  {
    INTEX0();
  }
}

void INTTIM0(void) interrupt 1 using 2  // Ausgelöster Interrupt 1 ->
1ms
{
  TF0 = 0;
  TH0 = 0xF8;      // 1ms Reload bei 24 MHz
  TL0 = 0x27;

  if(flag==0)
    flag = 1;

}

void init()
{
// Timer 0 & Timer 1 Aus!
  TCON = 0x00;
// Timer 0 16 Bit Zähler / Timer 1 16 Bit Zähler!
  TMOD = 0x11;
// Timer 0 : 1ms Reload bei 12 MHz
  TH0 = 0xFC;
  TL0 = 0x0F;

// Timer0 Interrupt Enable
  ET0 = 1;
  ET1 = 1;        // Timer1 Interrupt Enable

  TF0 = 0;



  EX0 = 0;        // Enable External Interrupt 1
  IT0 = 1;        // Flankengesteuert!

  IP0 |= 0x01;      // Zeitmessung Maximale Priorität!!! INTERRUPT
genauigkeit verbessern!
  IP1 |= 0x01;

  EAL = 1;        // Enable all Interrupts
}

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void timer_start()
{
  TR0 = 1;        // Timer0 Einschalten!!
}



void run()
{
if( new_messure == 1 )
{
new_messure = 0;
freq = 40000000/(unsigned long)(65536*overlap+pw_high*256+pw_low);
}
    // EX0 Aktivieren für Nächsten Pulse!
    if(new_messure==0 && EX0 == 0)
      EX0 = 1;
}

void main()
{
  init();
  overlap = 0;
  flag = 0;

  IP0 = 1;
  timer_start();      // Timer Starten und auf ins vergnügen!!

    while(1)
    {
      if( flag==1 )
      {
        run();
        flag = 0;
      }
    }

}




so mehr Beschreibung?

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jo, besser.
Schau ich mir morgen an, wenn nicht inzwischen einer was findet.

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gut ich warte

Autor: Brooks (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Periodenmessungsfehler durch die Interrupts?

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiss ich noch nicht,

der AT89C2051 nimmt die Interrupts nicht immer sofort an, vl arbeitet
er im Hintergrund an einem Anderen Interrupt, tatsache ist das 2
verschiedene Interrupts permanent angesprochen werden, 1. der Interrupt
des 1ms Timers ( T0 ), 2.tens der Externe Interrupt der eigentlich ERST
freigegeben wird wenn Timer0 Gerade fertig geworden ist damit keine
Collisions entstehen. Zumindest so das konzept, aber der Ritt auf
Interrupts is wie der Ritt auf einer 10m Welle, wenn man ganz rauf will
fällt man auch schnell mal ganz runter.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal mein Frequenzmesser (0,5Hz ... 125MHz):

http://progshop.com/elektronik/diskussion/messages...


Peter

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie ich sehe benutzt du den Timer Mode 3 falls ich das richtig
geschnallt habe, 2 counter und eine Timebase.

Ich versteh noch nicht ganz wie du "Pulsweiten" mit dem ding messen
kannst, oder misst du da nur die Pulse pro zeiteinheit?

auf jeden fall is es ein Rettungsring an dem man sich mal anklammern
kann, danke =)

lg Jan

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das programm is ned hilfreich das du auf halben Amplitudenmessung übers
Gate fährst. dh.: du gehst von einer 1:1er Puls Pausen verhältnis aus.
Das is bei mir ned der fall.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jankey,

wen meinst Du ?

Mein Programm mißt nur die Frequenz, keine Impulsdauer.
Das Tastverhältnis ist also völlig egal.

Es erfolgt immer eine Messung über volle Periodendauern von einer
0-1-Flanke bis zur nächsten 0-1-Flanke nach etwa 0,5s.

Dadurch ergibt sich unabhängig von der Frequenz eine gleichbleibend
hohe Auflösung.


Peter

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie geht das? du gehts ja beim T0 eingang für HF und beim T1 Eingang für
NF, wie kannst du über einen T timer Eingang Perioden messen ohne
Interrupt noch dazu +nedversteh+

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke ich werde einen anderen Controller nehmen, der halt
Pincompatibel ist.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"wie geht das?"

ganz einfach.
Schau Dir mal diese Sequenz an:
i = TL0;
    while( i == TL0 )
...

Wenn die nächste Flanke kommt, zählt er eins weiter und damit ist der
Timer ungleich dem vorherigen Wert und die Schleife wird verlassen.


Mein Programm mißt auch ständig weiter, d.h. es wird immer die
Differenz von der jetzigen zur vorherigen Auslesung gebildet.

Das hat den Vorteil, daß man bei 1Hz auch alle 1s eine neue Ablesung
erhält.

Wenn man den Timer stoppen und wieder starten würde, muß man immer noch
eine Flanke warten und würde bei 1Hz nur alle 2s einen neuen Wert
erhalten.

Das Auslesen der Timer im freien Lauf ist natürlich etwas tricky, da ja
genau dabei ein Übertrag kommen kann. Deshalb die nachfolgenden
Überlauftests und Korrekturen.

Den Bereichstest und Umschaltung kannst Du ja weglassen, ist erst ab
über 10MHz nötig.


Ein anderer Prozessor wird Dir nichts nützen.

Höchstens ein LPC2xxx von Philips (ARM7), da der 32Bit ist und auch
32Bit-Timer hat, dann entfallen die Übertragseffekte.


Peter

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mhm, dh.: der Timer wird mit dem Gate aktiviert, klingt nach einer
Coolen Polling methode, hoffe es geht sich mit all meiner
Anzeigekramerei aus. Werd das mal probieren

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aja fast hätt ich es vergessen: ein kleines Bild mit der
Anzeigeeinheit:

http://www.theng.at/html/modules/coppermine/albums...

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so umgebaut, programmiert, das kann ned funktionieren, das Ding erkennt
zwar flanke, aber bei nächsten Zyklus is das Gate noch immer high und
wird wieder durchlaufen nur halt mit sehr sehr kleinem Zahlenwert, hast
du das ding denn auch Mechanisch aufgebaut und es funktioniert?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ist nichts mit nem Gate drin, beide Zähler laufen ständig durch, der
Zähler der Zeitbasis (interner Quarz) und der Zähler des
Eingangssignals.

Das Auslesen wird nach der gewählten Updatezeit auf die nächste Flanke
des Eingangssignals synchronisiert, damit man immer volle Perioden
hat.

Sonst würde man ja erhebliche Ungenauigkeiten bekommen.


Klar sind alle meine Beispiele funktionsfähig und ausprobiert.


Peter

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Counter?

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie synchronisierst du auf die nächste flanke? ah ah ah ,,, durch den
Counter, verstehe!

Autor: Jankey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm, also 1x counter 1xtimer, bräuchte aber noch einen timer für die
Anzeigt die im 1ms Takt getriggtert wird.

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.