Frequenzmessung mit 2051

Gast #146880
also ich fasse mich kurz, ich hab eine Schaltung mit der ich Frequenzen
bzw Periodendauern messen will... in benutzung:

EX0 zum aufnehmen des Pulses!
Timer1 zum zählen der Zeit... ( Quarz= 12Mhz)

lass ihn von 0 bis 65536 durchlaufen bis ein Puls von EX0 kommt, dabei
zeige ich dann nur die Zeit an, in gewissen interwallen, sodala jetzt
hab ich allerdings meinen Frequenzgenertor drangehänt und fahre mit
einer Konstanten Frequenz die ich messen will...

problem: wenn ich eine Periodendauer von 5ms eingestellt habe zeigt er
alles mögliche an zwischen 5084 - 4600 an.
Gast #146882
16 Bit Timer, wenns nen überlauf gibt dann zählt er eine Variable mit
und multipliziert dann mit 65536, TH1 wird mit 256 multipliziert und
TL1 wird einfach so addiert ...

Beispiel:
er hat 9900uS zwischen den Pulsen... zählt aber mal um +150 drüber oder
-150 drunter ... er schwankt einfach wie wild ...
Gast #146884
#define WP P1            // Working Port
#define AP P3            // Addressierung Port
#define uchar unsigned char

   sbit bTaster   = P3^0;  // Setz taste für die RPM Shift light
   sbit bInput   = P3^2;  // Puls Input, 6 Zylinder, 2 Umdrehungen = 3
Pulse/umdrehung wegen 4-Takt
   sbit bSL     = P3^7;  // Shift light

  uchar disp[4];      // Display Value
  uchar cTable[] = {   0x0A,      // 0      // Werte Tabelle für 7 
Segmente
                0x9F,      // 1
                0x29,      // 2
                0x0D,      // 3
                0x9C,      // 4
                0x4C,      // 5
                0x48,      // 6
                0x1E,      // 7
                0x08,      // 8
                0x0C  };     // 9

  uchar port;    // Welcher gerade Aktiv ist!
  unsigned long value;    // Aktiver Wert!
  unsigned long time;
  unsigned int array[10];
  uchar overlap;

  uchar t_overlap;
  uchar t_high;
  uchar t_low;

  uchar counter;
  uchar temp;

// Interrupts
void INTEX0(void) interrupt 0 using 2;      // Externer Interrupt 0
void INTTIM0(void) interrupt 1 using 2;      // Timer0
void INTTIM1(void) interrupt 3 using 2;      // Timer1
void setChar( uchar display_value );

// Initialisierungen
void init();    // Initialisieren des Timer0 & Externen Interrupts!!!
void setBCDport();

void char2display(int input)
{
  disp[0] = input / 1000;
  input  -= disp[0] * 1000;
  disp[1] = input / 100;
  input  -= disp[1] * 100;
  disp[2] = input / 10;
  input  -= disp[2] * 10;
  disp[3] = input;
}

////////////////////////////////////// Initialisierungen
///////////////////////////////////////
//////////////////////////////////////////////////////////////////////// 
////////////////////////
//////////////////////////////////////////////////////////////////////// 
////////////////////////

void INTEX0(void) interrupt 0 using 2
{
  bSL = !bSL;
  TR1 = 0;                    // Beide Timer ausschalten!
  TR0 = 0;
  t_overlap = overlap;
  t_high=TH1;
  t_low =TL1;
  overlap = 0;
  TH1 = 0;
  TL1 = 10;                  // Mit 10 vorladen!
  TR1 = 1;                          // Timer 1 Wieder einschalten!!!
  TR0 = 1;                    // Timer 0 Wieder einschalten!!

  // Wert ausrechnen!!!
  value = t_overlap*65536+t_high*256+t_low;  // Wert Einlesen!
}

void INTTIM0(void) interrupt 1 using 2  // Ausgelöster Interrupt 1 ->
1ms
{
  TH0 = 0xFC;      // 1ms Reload bei 12 MHz
  TL0 = 0x0F;
  TF0 = 0;        // Interrupt Flag Löschen!
  TR0 = 1;        // Timer0 Einschalten!!

  counter++;

  if ( (counter-1)%20 == 0 )
    array[(counter-1)%20] = 20000000/value;

  if (counter == 199)    // Neuer wert alle 180ms
  {
    counter = 0;
      time = 0;

     for (temp=0;temp<10;temp++)
         time += array[temp];
//      time /= 10;

//    time = 20000000/value;  // Bei 15hz is schluss... Reason: 1/x
    //  time = value;

    if (time>9999)
      time = 9999;
  }
    WP = 0xFF;          // Damit keine Randbereiche Rot beleuchtet sind!
      char2display(time);    // Umrechnen auf 4 Bytes!
      setBCDport();        // Nächste Anzeige Adressieren!
      setChar(disp[port]);    // Zeichen In die Anzeige Legen!
}

void INTTIM1(void) interrupt 3 using 2
{
  overlap++;
  TH1   = 0;                  // Timer 1 wieder auf 0 zurücksetzen!!!
  TL1   = 0;
  TR1   = 1;                  // Timer 1 Einschalten!!!
}

void timer_start()
{
  TH0 = 0xFC;      // 1ms Reload bei 12 MHz
  TL0 = 0x0F;

  TH1 = 0;        // Timer 1 auf 0 setzen!
  TL1 = 0;

  TR0 = 1;        // Timer0 Einschalten!!
  TR1 = 1;        // Timer1 Einschalten!!
}

void init()
{
  bSL = 1;
  counter = 0;
  port = 3;      // Port auf 3 setzen! ( start mit 0 )
  TCON = 0x00;    // Timer0 & Timer1 Aus!
  TMOD = 0x11;    // Timer 0 16 Bit Zähler / Timer 1 16 Bit Zähler!
  ET0 = 1;        // Timer0 Interrupt Enable
  ET1 = 1;        // Timer1 Interrupt Enable

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

  TF0 = 0;

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

  EAL = 1;        // Enable all Interrupts
}

void setChar( uchar display_value )
{
  WP = cTable[display_value];
}

void setBCDport()
{
   port++;        // port shifterei ...
  if (port == 4)
    port = 0;

  AP |= 0x3A;    // Alle Adressierungen Löschen!
  if (port == 0)
    AP &= 0xFD;
  if (port == 1)
    AP &= 0xDF;
  if (port == 2)
    AP &= 0xEF;
  if (port == 3)
    AP &= 0xF7;
}


void main()
{
  init();
  timer_start();      // Timer Starten und auf ins vergnügen!!
    while(1)
      ;
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.