Frequenzmessung mit 2051

Gast #146880
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.
Gast #146882
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 ...
Gast #146884
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)
      ;
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren