Forum: Mikrocontroller und Digitale Elektronik Frequenzmessung mit 2051


von Jankey (Gast)


Lesenswert?

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.

von Hubert (Gast)


Lesenswert?

Wie lang ist die Zeit bis der Timer durchgelaufen ist? Kommt es zu einem
Überlauf oder ist er zu langsam?

von Jankey (Gast)


Lesenswert?

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 ...

von michi (Gast)


Lesenswert?

setzt du den timer wieder zurück wenn ein Impule an EX0 erfasst wurde?
Am besten schreibste mal deine Source in den Thread.
mfg

von Jankey (Gast)


Lesenswert?

#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)
      ;
}

von Jankey (Gast)


Lesenswert?

zu garkeiner eine Idee?

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.