Forum: Mikrocontroller und Digitale Elektronik Stoppuhr mit TIMER


von Serieousl L. (stephan2013)


Lesenswert?

Hallo,
Ich will ein Stoppuhr- Programm schreiben mittels Timer.

Also die Uhr funktioniert schon aber das mit Stoppen und wieder starten 
haut nicht hin.
Wenn ich auf Stop drücke stoppt die Uhr vllt nach 3-4 Sekunden aber auch 
nicht immer -.-
Das Programm is für einen Luminary Mikrocontroller.
Hier der Code:
1
int main (void) 
2
{
3
  int sek = 0;
4
  int min = 0;
5
  int stunde=0;
6
  // int i=0;
7
  int statusUp = 0;
8
  int statusDown = 0;
9
10
11
  char ausgabe[50]; 
12
13
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);   // port f enablen
14
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);   // port e enablen
15
16
  GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1);    //Configures PIN0, PORTF for use as GPIO input --> Up- und Down-Taster
17
  
18
  GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);  //Aktiviert Pull-Up Widerstand  für Select Taster
19
  GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 , GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);  //Aktiviert Pull-Up Widerstand für Up- und Down-Taster
20
    
21
22
  GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_1);   //Setze den PIN_1(Select-Button) als Input
23
  GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
24
25
26
  RIT128x96x4Init(1000000); //SPI-Takt
27
28
  //Set the clocking
29
  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);
30
  // Peripherie aktivieren (Timermodul 0,GPIOs)
31
  SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
32
  //Timermodul 0 als periodischer 32-Bit Timer konfigurieren
33
  TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
34
  //Timervorladewert für Ablauf nach 1 Sekunde bei 8MHz-Takt fixieren
35
  TimerLoadSet(TIMER0_BASE, TIMER_A, 8000000)  ;
36
  //Timer A des Timer0 freigeben
37
  TimerEnable(TIMER0_BASE, TIMER_A);
38
39
  while(1)
40
  {
41
    while (TimerIntStatus(TIMER0_BASE,false) != TIMER_TIMA_TIMEOUT);
42
           //warten, bis Timer A des Timermodul 0 den Wert 0 erreicht hat
43
    
44
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);     // Flag löschen
45
    sek++;                           // Sekundenzähler erhöhen
46
    
47
    // Stoppen
48
    if((GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_0) == 0) && (statusUp == 0))
49
    {
50
      // TimerDisable(TIMER0_BASE, TIMER_A); // Timer stoppen
51
      TimerDisable(TIMER0_BASE, TIMER_A);
52
      statusUp = 1;
53
    }
54
    else if(GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_0)!= 0) // wenn taster losgelassen wird
55
    {
56
        statusUp=0;                       
57
    }
58
59
    // wieder starten
60
    if((GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_1) == 0) && (statusDown == 0))
61
    {
62
      // TimerDisable(TIMER0_BASE, TIMER_A); // Timer stoppen
63
    TimerEnable(TIMER0_BASE, TIMER_A);
64
      statusDown= 1;
65
    }
66
    else if(GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_0)!= 0) // wenn taster losgelassen wird
67
    {
68
        statusDown=0;                       
69
    }
70
    
71
    if(sek == 60)                         // Wenn sekunde = 60 ==> 1 Minute
72
    {
73
      sek=0;
74
      min++;    
75
    }
76
    if(min == 60)                         // Wenn minute = 60 ==> 1 Stunde
77
    {
78
      min=0;
79
      stunde++;
80
    }
81
    if(stunde == 24)
82
    {
83
      sek=0;
84
      min=0;
85
      stunde=0;  
86
    }  
87
    sprintf(ausgabe, "Zeit : %02i:%02i:%02i",stunde,min,sek);           // Stunde, Minute und Sekunde in String konvertieren
88
    RIT128x96x4StringDraw(ausgabe, 10, 24, 15);
89
    
90
  
91
  }
92
}

von Karl H. (kbuchegg)


Lesenswert?

> Ich will ein Stoppuhr- Programm schreiben mittels Timer.

Dann solltest du dir mal ansehen, was du mit dem Timer sonst noch so 
machen kannst. Zum Beispiel, wei man da bei einem Overflow eine 
Interrupt Routine drann hängt.

Das hier
1
    while (TimerIntStatus(TIMER0_BASE,false) != TIMER_TIMA_TIMEOUT);
ist effektiv kein Ersatz dafür. Denn an dieser Stelle wartet dein 
Programm auf den Überlauf des Timers.
Solange dein Programm nicht mehr machen soll, als die Zeit zählen, mag 
das noch angehen. In dem Moment, in dem dein Programm aber nebeher auch 
noch andere Dinge machen soll, wie zb ein paar Taster überwachen, ist so 
etwas nicht tragbar.

Und spätestens, nachdem du hier
1
    if((GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_1) == 0) && (statusDown == 0))
2
    {
3
      // TimerDisable(TIMER0_BASE, TIMER_A); // Timer stoppen
4
    TimerEnable(TIMER0_BASE, TIMER_A);
5
...
den Timer überhaupt abgeschaltet hast, wird dann die erst genannte 
Schleife bis zum St. Nimmerleinstag warten. Da wird dann kein Timeout 
(ich nehme mal an, dass das ein Overflow ist) mehr kommen. Denn ... der 
Timer läuft ja nicht.


Fazit: so gehts nicht.
Die vernünftigste Lösung ist eine Trennung des Uhrenmechanismus von den 
Tasten. Wenn dein Timer Interrupts kann (wovon ich mal stark ausgehe), 
dann  besteht die Lösung darin, die Uhr als Ganzes (ohne AUsgabe) im 
Interrupt zu machen und die Tasten in der Hauptschleife zu behandeln.

: Bearbeitet durch User
von Serieousl L. (stephan2013)


Lesenswert?

zuerst danke für die Antwort
Also mir wurde gesagt in der Schule, dass ich das ohne Interrupts machen 
muss.

Und wie meinen Sie das, dass ich das mit der Tastenabfragung auserhalb 
verwenden soll ?

von Karl H. (kbuchegg)


Lesenswert?

Serieousl Lesrely schrieb:
> zuerst danke für die Antwort
> Also mir wurde gesagt in der Schule, dass ich das ohne Interrupts machen
> muss.

Ok.
Dann aber bitte so
1
  while(1)
2
  {
3
    if( TimerIntStatus(TIMER0_BASE,false) == TIMER_TIMA_TIMEOUT)
4
    {
5
      .. Timer Überlauf behandeln.
6
         Uhr weiterzählen und Anzeige auf neuesten Stand bringen
7
    }
8
9
    Tasten behandeln
10
  }


In der Hauptschleife müssen die Tasten IMMER behandelt werden und nicht 
nur zu jeder vollen Sekunde!

von Serieousl L. (stephan2013)


Lesenswert?

Vielen Danke jetzt funktioniert es !
Tut mir leid wenn ich so viel frage :

Was macht diese Zeile genau:
1
if( TimerIntStatus(TIMER0_BASE,false) == TIMER_TIMA_TIMEOUT)

Und wieso hat das von mir nicht vorher gestimmt
ich muss ja abfragen während er zählt oder?
Wie du es gemacht hast überprüft er die Tasten zum Schluss oder wie ?

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.