Forum: Mikrocontroller und Digitale Elektronik Taktzyklus Timer at89c51ed2 Berechnung


von at89c51ed2 (Gast)


Lesenswert?

hallo,

ich habe mir für das einarbeiten und probieren ein board zugelegt 
(schematic: 
http://www.steitec.net/media/products/0326136001309158401.pdf ).

ich wollte nun leds im minutentakt ein und ausschalten.

Am At89c51ed2 hängt ein 29,4912 MHz Quarz. Der X2 Mode ist nicht 
eingeschaltet, daher 29,4912MHz/12. Das Reziproke davon ist 0,406901µs.

Um 0,01s zu erreichen werden also 24576 Zyklen benötigt.
Daher setze ich den Timer auf 9FFF(40959) um nach 24576 zyklen ein 
Interrupt zu bekommen.

Ich lasse nun bei jedem Interrupt eine Variable mit zählen und wenn 
diese 6000 erreicht hast soll die led getoggled werden. (6000*0,01s 
=60s)

Jedoch sieht das wenn ich das ausprobiere ganz anders aus. Es sind so ca 
3 sekunden bis das ganze geschieht.

Wieso ist meine Berechnung denn falsch?

von HolgerT (Gast)


Lesenswert?

Welchen Timer-Modus benutzt Du? Reload-register richtig initialisiert? 
Bitte zeige den Code.

-holger

von at89c51ed2 (Gast)


Lesenswert?

natürlich gern:

#include "at89c51xd2.h" //Headerdatei für Controller
void int_routine(); //Funktion delay deklarieren

void main(void)    //Hauptfunktion main
{
  EA=1;        //enable all interrupts
  ET0=1;       //enables Timer 0 overflow interrupt
  TMOD=0x01;
  TH0=0x9f;
  TL0=0xff;
  TR0=1;

  do
  {
  }while(1);
}

void int_routine() interrupt 1  //Programmcode für Funktion delay
{ static unsigned int i;
  i++;
  if(i ==  6000)
  {
    if(P0 == 0xFF)
    {
    P0 = 0x00;
    }
      else
      {
      P0 = 0xFF;
         }
   i = 0;
  }
  TR0 =0;
  TL0 = 0x9f;
  TH0 = 0xff;
  TR0 = 1;

}

von Jobst M. (jobstens-de)


Lesenswert?

Du möchtest Reload mit 16-Bit haben.
Warum benutzt Du nicht Timer 2 im Auto-Reload-Mode?
Bei Deiner Methode gehen ständig Takte verloren.


at89c51ed2 schrieb:
> Wieso ist meine Berechnung denn falsch?

Ist sie fast nicht.
Du möchtest alle 24576 Takte einen Überlauf. Der Überlauf passiert bei 
0xFFFF -> 0x0000/0xA000 -> 0xA001 .... 0xFFFF -> 0x0000/0xA000
Mit anderen Worten: 0x9FFF ist falsch.
Von 0x9FFF zählst Du 24576 Takte bis 0xFFFF + 1 Takt = 0x0000/0x9FFF
=24577 Takte (zzgl. den Krempel, den Du in der IRQ-Routine 
veranstaltest)

Aber das ist nicht Dein Problem. Dein Problem liegt Faktor 20 daneben.
Exakt 23.4375 ...

Verringere mal
> if(i ==  6000)
 solange, bis Du eine Veränderung entdeckst. Vielleicht kommst Du dann 
drauf ...


Ach ja:

at89c51ed2 schrieb:
> if(P0 == 0xFF)
>     {
>       P0 = 0x00;
>      }
>     else
>     {
>       P0 = 0xFF;
>      }

P0 = 0xFF - P0;



Gruß

Jobst

von at89c51ed2 (Gast)


Lesenswert?

Danke schonmal, das stimmt habe den einen fehlenden Takt nicht mit 
eingerechnet!
Und Dank der Quelltextoptimierung wird die ISR schneller beendet, ok.

Werde mich nachher mal dran machen das Ganze mit Timer 2 im Autoreload 
zu probiere und dabei auch die if-Bedingung ändern.

Woher der Faktor ~20 kommt, weiß ich noch nicht, aber vllt. geht mir 
beim probieren ja wirklich ein Licht auf ^^


Gruß

von Matthias (Gast)


Lesenswert?

at89c51ed2 schrieb:
> Am At89c51ed2 hängt ein 29,4912 MHz Quarz.

Sicher das es ein Grundton-Quarz ist! Die sind über 24MHz ehr selten. 
Vielleicht läuft Dein System auf falscher Wellenlänge;-))

von at89c51ed2 (Gast)


Lesenswert?

also ich hab das ganze jetzt mal umgeschrieben, also Timer 2 reload 
modus mit interrupts und was noch so aufgefallen war.

In der Simulation macht er zwar, was er sollte, aber hier an meinem 
Board sehe ich nichts. Es möchte einfach nichts leuchten...

#include "at89c51xd2.h" //Headerdatei für Controller
void int_routine(); //Funktion delay deklarieren

void main(void)    //Hauptfunktion main
{
  EA=1;
  ET2=1;
  RCAP2H=0xFF;
  RCAP2L=0xFD;
  TL2=0x00;
  TH2=0xA0;
  TR2=1;
  do
  {
  }while(1);
}

void int_routine() interrupt 5  //Programmcode für Funktion delay
{ static unsigned int i;
  i++;
  if(i ==  6000)
  {
    P1=0xFF-P1;
    i=0;
  }
  TF2=0;
}


zum Quarz: Dazu kann ich leider nichts weiter sagen, da dem Board 
(leider) nur Datenblätter zum Mikrocontroller, das Instruktion set von 
8051ern, das Schematic und ein paar Beispielprogramme beigelegt waren.
Auf dem Quarz steht auch einfach nur "KDS 29,4912MHz"...

Gruß

von at89c51ed2 (Gast)


Lesenswert?

achso, ich hatte RCAPL und RCAPH noch vom ausprobieren falsch...

Allerdings ist mir auch aufgefallen, das das blinken der LED erst 
beginnt, sobald ich die spannungsversorgung einmal abgemacht habe und 
wieder anschließe...

von at89c51ed2 (Gast)


Lesenswert?

Aber   if(i ==  6000) liefert jetzt das gewünschte Ergebnis! =)

Vielen Dank für eure Hilfe!!!

Also erstmal nur noch die letzte Frage, weshalb muss ich die Batterie 
aufeinmalzuvor abnehmen?

von Jobst M. (jobstens-de)


Lesenswert?

at89c51ed2 schrieb:
> Also erstmal nur noch die letzte Frage, weshalb muss ich die Batterie
> aufeinmalzuvor abnehmen?

Okay, dann liegt es am Quarz.


Gruß

Jobst

von test1234 (Gast)


Lesenswert?

inwiefern liegt das denn am Quarz,  dass die Versorgungsspannung nochmal 
abgeschaltet werden muss? Bei vorherigen Programmen musste ich das ja 
auch nicht machen(daher ist es mir ja aufgefallen).

Gruß

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.