Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Assembler » Timer

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
27.04.2005, 21:11 Uhr
duedel



hallo,

ich habe folgendes problem wenn der counter auf 80 gesetzt wird läuft der timer zu langsam, aber die schritte werden jeweils um 1 erhöt. wird der counter niedriger ausgewählt zb: 20 sitmmt zwar die sekundenzeit aber die schritte sind in 3er bzw 4er schritten.

weiß jemand woran dies leigen kann?? oder gibt es eine alternative dies besser zu schreiben?? danke schon mal für eure hilfe. mfg duedel


hier ist noch der quellcode:
=======


C++:
void timer0 (void) interrupt 1       // Programmbeginn an Adresse 000Bh Interruptnr.:1
{                  // Dieser Programmteil wird alle 50msec aufgerufen bei
                  // Ueberlauf von Timer0
    int count;

    count++;        // Diese Variable wird jedesmal um 1 erhöht

    if(count==80)    // Dieser Programmteil wird somit jede Sekunde ausgeführt
    {
        sek++;
        count=0;

        if (sek > 59)         // Wenn die Variable sek > 59 ist,
        {
            min++;        // werden die Minuten um 1 erhöht und
            sek=0;        // die Sekunden auf 0 zurückgesetzt.    

            if (min > 59)    // Wenn die Variable min > 59 ist,
            {
                std++;    // werden die Stunden um 1 erhöht und
                min=0;    // die Minuten auf 0 zurückgesetzt.        
            }
        }    
    }

    TL0 = 0x3C;        // Timer0 wieder mit 15535dez laden = 3CAF hex
    TH0 = 0xAF;    
}


Dieser Post wurde am 27.04.2005 um 21:18 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
28.04.2005, 13:42 Uhr
ao

(Operator)



Zitat von duedel:
... aber die schritte sind in 3er bzw 4er schritten.

Was meinst du damit? Wird die Anzeige nur alle 3 oder 4 Sekunden aktualisiert? Wo passiert das denn? In deinem Code ist das nicht zu sehen.

Ein besserer Ansatz? Hmm ....
Ich würde in der Interrupt-Routine nur einen Zähler hochsetzen und die Umrechnung in Stunden, Minuten und Sekunden da machen, wo es gebraucht wird, also so:

C++:

volatile long int g_Ticks = 0; // globaler Zeit-Zähler

void timer0 (void) interrupt 1       // Programmbeginn an Adresse 000Bh Interruptnr.:1
{                  // Dieser Programmteil wird alle 50msec aufgerufen bei
                  // Ueberlauf von Timer0
    /* Das Zählregister sollte als erstes nachgeladen werden, nicht als letztes.
       Noch besser: Wenn der Timer sich selber nachladen kann, sollte man
       das nutzen. */

    TL0 = 0x3C;        // Timer0 wieder mit 15535dez laden = 3CAF hex
    TH0 = 0xAF;    

    g_Ticks++;    // Zähler raufsetzen und fertig
}



Wenn du dir jetzt noch merkst, wie lang ein Tick in Millisekunden ist, kannst du jederzeit aus dem Zählerstand die Zeit errechnen.

Übrigens ist das Code für einen Microcontroller, ist also unter Windows-API ganz sicher falsch. Klär mal, was du mit der Anzeige meinst, und dann finden wir auch ein passenderes Board für deine Frage.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
29.04.2005, 19:21 Uhr
~winner
Gast


also im prinzip ist euer prob ganz einfach zu lösen.
ihr müsst nur C richtig lernen
^^
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
29.04.2005, 19:35 Uhr
duedel



So hier habe ich den gesamten Quellcode angehängt. Er ist für den Microcontroller Atmel AT89S8252. Die Ausgabe erfolgt über ein LCD-Display.
Die Anzeige wird zwar jede Sekunde aktualisiert, aber es werden nicht die Schritte 1..2..3 angezeigt, sondern z.B 3..6..9..11. Sehr unregelmäßig jedenfalls.




Code:

/* Stoppuhr_Main.c *********************************************************************
*                    
*            zum Projekt gehört die Datei lcd_Help.c  
******************************************************************/
#include <reg51.H>

#include <stdio.h>            // für sprintf                                            

extern void initlcd (void);        //    Initialisierung LCD-Display an P0            
extern void loeschenlcd (void);
extern void textlcd (unsigned char *text,unsigned char zeile);



unsigned char buf [14] ;

/*  P3  */
sbit P3_0 = 0xB0;    // zurücksetzen
sbit P3_1 = 0xB1;    // anhalten
sbit P3_2 = 0xB2;    // start / weiter (externer Interrupt 0)
sbit P3_3 = 0xB5;    // Zwischenzeit nehmen (externer Interrupt 1)
sbit P3_7 = 0xB7;    // Hilfe


int sek;    // Variable für Sekunden
int min;    // Variable für Minuten
int std;    // Variable für Stunden



void extInt0 (void);         // Interrupt-Service-Routine extInt0 deklarieren     s.u.    
void extInt1 (void);         // Interrupt-Service-Routine extInt1 deklarieren     s.u.        



/*********** Methode zur Ausgabe der Zeit ***************/

void ausgabe (int zeile)
{
             sprintf (buf,"%02d:%02d:%02d",std,min,sek);    // schreibt die komplette Zeitanzeige in den Buffer
// 2: für jede Variable werden 2 Anzeigestellen reserviert
    textlcd (buf,zeile);        // Ausgabe des Bufferinhaltes        
}



void main (void)
{
    initlcd ();                    // Initialisierung LCD-Display an P0                    
    loeschenlcd ();                // Anzeige löschen    

    

/************* Konfiguration von Timer 0 *************/
    TL0 = 0x3C;        // Nachladewert 3CAF in Timerregister 0 schreiben.
    TH0 = 0xAF;        // Ergibt 50msec bis Ueberlauf bei Quarz 12 MHz
    TMOD = 0x01;    // Timer0 im Modus2 16bit Zaehler
    TCON = 0x11;    // Start Zaehler0
    TR0 = 0;
    PT0    = 1;        // setzt Timer0-Interrupt auf höhere Priorität


    ET0 = 1;        //Interrupt Timer0 freigeben


    
/************* Initialisierung Interrupt 0 ************/

    EX0 = 1;        // ext. Interrupt0 freigeben
//    IE0 = 1;    
    PX0 = 0;        // setzt externen Interrupt0 auf niedrigere Priorität



/************* Initialisierung Interrupt 1 ************/

    EX1    = 1;        // ext. Interrupt1 freigeben        
    PX1 = 0;        // setzt externen Interrupt0 auf niedrigere Priorität
            
    
    EA    = 1;        // globale Interruptfreigabe                                            

    

/****************** Hauptprogramm *********************/

// eine Endlosschleife, die nur durch die Interrupts unterbrochen wird
    
    while (1)
    {    
        // Zeit zurücksetzen
        if (P3_0==0)        
        {
            TR0  = 0;
            sek  = 0;
            min     = 0;
            std  = 0;
            loeschenlcd();
            ausgabe(1);
        }

        

        // Stoppuhr anhalten
        if (P3_1==0)
        {
            TR0 = 0;
         }
        

                 // Anleitung
        if (P3_7==0)
        {
            loeschenlcd();
            textlcd ("Mit 'S2' gelangen Sie in den Stoppuhrmodus und koennen die Stoppuhr zuruecksetzen.",1);
        }
        
        ausgabe(1);      // Zeitausgabe in Zeile 1 erfolgt
    }
}


        
/****************** Interrupt-Routine Timer 0 ********************/

void timer0 (void) interrupt 1        // Programmbeginn an Adresse 000Bh Interruptnr.:1
{                    // Dieser Programmteil wird alle 50msec aufgerufen bei
                    // Ueberlauf von Timer0
    int count;

    count++;        // Diese Variable wird jedesmal um 1 erhöht

    if(count==20)    // Dieser Programmteil wird somit jede Sekunde ausgeführt
    {
        sek++;
        count=0;

        if (sek > 59)         // Wenn die Variable sek > 59 ist,
        {
            min++;            // werden die Minuten um 1 erhöht und
            sek=0;            // die Sekunden auf 0 zurückgesetzt.    

            if (min > 59)        // Wenn die Variable min > 59 ist,
            {
                std++;            // werden die Stunden um 1 erhöht und
                min=0;            // die Minuten auf 0 zurückgesetzt.        
            }
        }    
    }

    TL0 = 0x3C;        // Timer0 wieder mit 15535dez laden = 3CAF hex
    TH0 = 0xAF;    
}



/****************** Interrupt-Routine externer Interrupt 0 ********************/

void extInt0 (void) interrupt 0        // Interrupt 0 hat Einsprungadresse 0003h    Portpin P3.2
{    
    TR0 = 1;        // Timer starten
}



/****************** Interrupt-Routine externer Interrupt 1 ********************/

void extInt1 (void) interrupt 2        // Interrupt 1 hat Einsprungadresse 0013h    Portpin P3.3                        
{
    ausgabe(2);        // Zwischenzeit ausgeben    
                // aktuelle Zeit wird in der zweiten Zeile des LCD-Displays ausgegeben
}





 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
29.04.2005, 20:07 Uhr
Spacelord
Hoffnungsloser Fall



Zitat von ~winner:
also im prinzip ist euer prob ganz einfach zu lösen.
ihr müsst nur C richtig lernen
^^


Hat hier irgend jemand die 0 gewählt?

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
29.04.2005, 20:55 Uhr
ao

(Operator)



Zitat von ~winner:
also im prinzip ist euer prob ganz einfach zu lösen.
ihr müsst nur C richtig lernen
^^

Na dann mal los, du Oberschlauer. Wir sind ganz Ohr.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
29.04.2005, 21:08 Uhr
ao

(Operator)


Also ich seh da nix Eindeutiges. Mal n paar Vorschläge:

Die externen Interrupts, sind die flanken- oder levelgetriggert? Soll heißen, kommen die genau einmal oder rasen die durch, solange du die Taste hältst?

Und wie gut sind die LCD-Routinen ausgetestet? Können die vielleicht noch ein vermurkstes Timing haben? Ich weiß aus Erfahrung, dass LCDs fummelig sein können.

Hast du ein Oszilloskop oder einen Laborzähler zur Verfügung und kannst in den ganzen Routinen mal mit ein paar freien Digitalausgängen wackeln, so dass du ne Vorstellung bekommst, wie oft sie laufen?

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
30.04.2005, 12:41 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


kann es einfach sein, das du was vergessen hast?

Nämlich die Überprüfung ob die interrupt-routine durch Extern oder durch Timer ausgelöst wurde?
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
30.04.2005, 19:18 Uhr
ao

(Operator)


Er hat doch drei Interrupt-Routinen, eine für den Timer (und nur für den) und zwei externe für die Taster.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
30.04.2005, 19:42 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


hmm jo übersehen (kommt davon wenn man immer die posts nicht richtig liest )
evtl unterbrechen die anderen routinen den programmablauf so, das auch die timer-methode unterbrochen wird?
Beim PIC deaktiviert man in der Int-Funktion das Generelle Auslösen von Int's und am ende aktiviert man das wieder, damit die int-funktion nicht selbst unterbrochen wird.

ansonsten kostet dich das zeit berechnen in der int-routine zuviel zeit.
--
class God : public ChuckNorris { };

Dieser Post wurde am 30.04.2005 um 19:42 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ Assembler ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: