Forum: Mikrocontroller und Digitale Elektronik Countdowntimer mit Vorwarnung


von Sebastian M. (basti87)


Angehängte Dateien:

Lesenswert?

Sehr geehrte Mikrocontroller Gemeinde,

ich bin ein Maschinenbaustudent und der Meinung das die Elektrotechnik 
in meinem Studiengang generell zu kurz kommt. Daraufhin habe ich mich 
entschieden meinen Horizont selber zu erweitern. Daher bin ich Neuling 
auf dem Gebiet der Mikrocontrollerprogrammierung.

Da ich in meinem vorherigen Bildungsweg in C und auch in Java 
programmiert (rumgespielt trifft es eher) habe werde ich bei C bleiben 
und nicht in Assembler programmieren.

Ich wollte nun mein erstes Projekt starten. Ausgesucht habe ich mir den 
so oft für sehr einfach befundenen "Countdown Timer". Leider musste ich 
feststellen, dass dieser doch nicht so einfach ist.

Folgende Idee:
CountdownTimer mit LCD Anzeige (16x2, 4Bit), der mittels vier Tastern 
auf die gewünschte Zeit eingestellt wird.

S1 - Zeit einstellen; S2 - Stunde um "x" erhöhen; S3 - Minute um "y" 
erhöhen, S4 - Sekunde um "z" erhöhen.

Bei der Einstellung der Zeit muss S1 gedrückt bleiben. Während der 
Einstellung soll in der ersten Zeile des Displays "Einstellung" stehen 
und in der zweiten Zeile soll die Zeit in Form von "00:00:00" blinken.
Durch loslassen von S1 soll nun in der 1. Zeile "Bereit" stehen.

Durch einen weiteren Taster (S5) soll der Countdown gestartet werden. 
Die Anzeige zeigt in der ersten Zeile "läuft" an und in der zweiten 
Zeile die runter laufende Zeit "01:59:59".

Beim Erreichen der Zeit "00:01:00" soll ein Ausgang geschaltet werden.
Beim Erreichen der Zeit "00:00:30" soll ein Ausgang impulsartig 
geschaltet werden und beim Erreichen von der Zeit "00:00:10 soll ein 
weiterer Ausgang geschaltet werden.

Ist der Countdown abgelaufen soll im Display "Spiel vorbei" angezeigt 
werden. Durch den Taster (S6) soll der Countdown jeder Zeit abgebrochen 
werden, wobei im Display dann in der ersten Zeile "gestoppt" steht und 
in der zweiten Zeile die Zeit "00:45:23" zu der der Schalter betätigt 
wurde.

Nähere Angaben siehe Ablaufdiagramm.

Mein Problem besteht jetzt in der Ausführung, ich habe mir das STK 500 
und ein LCD besorgt. Am löten und der Hardware scheitert es nicht. Eher 
an der Software. Benutzen tue ich die von Euch erstellten Dateien 
(lcd-routines.c /.h) unter Verwendung des Tutorials.

Übersicht:
S1 - Zeit einstellen
S2 - Stunde um "x" erhöhen
S3 - Minute um "y" erhöhen
S4 - Sekunde um "z" erhöhen
S5 - Countdown starten
S6 - Countdown abbrechen
S7 - Reset

Logik:
S1^S2 = std++
S1^S3 = min++
S1^S4 = sek++

Mein bisheriger Code:
1
/*
2
 * STK_500___ATMega_8515_test.c
3
 
4
 * ATMega 8515 @ 16 MHz
5
 
6
 * Created: 11.03.2013 14:54:52
7
 *  Author: Sebastian
8
 */ 
9
10
#include <avr/io.h>      // Namen der IO Register
11
#include <avr/delay.h>
12
#include <avr/interrupt.h>
13
#include <stdint.h>
14
#include <stdlib.h>
15
#include "D:/Eigene Dateien/Dokumente/Atmel Studio/STK 500 - ATMega 8515 test/STK 500 - ATMega 8515 test/lcd-routines.h"
16
17
18
// CPU Takt speichern
19
#ifndef F_CPU
20
#warning "F_CPU war noch nicht definiert, wird nun mit 3686400 definiert"
21
#define F_CPU 16000000L     // Takt als LONG definieren, da zu groß für Integer 
22
#endif
23
// ------------- Ende ---------------------
24
25
int main(void)
26
{
27
  
28
// Initialisierung des LCD
29
// Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
30
// verschwunden sein
31
    lcd_init();
32
33
  
34
  
35
  
36
  
37
// Eingänge definieren
38
DDRB = 0x00;            // Setzen aller Pins des Portes B als Input 0b00000000 = 0x00
39
PORTB = 0x00;            // Einschalten der internen PullUps = 0b11111111 = 0xff, Ausschalten = 0b00000000 = 0x00
40
41
42
// Ausgänge definieren
43
DDRD = 0xff;          // Setzen aller Pins des Portes B als Output 0b11111111 = 0xff
44
45
  
46
  
47
  
48
    // Text in einzelnen Zeichen ausgeben
49
    lcd_data( 'T' );
50
    lcd_data( 'e' );
51
    lcd_data( 's' );
52
    lcd_data( 't' );
53
    
54
    // Die Ausgabemarke in die 2te Zeile setzen
55
    lcd_setcursor( 0, 2 );
56
    
57
    // erneut Text ausgeben, aber diesmal komfortabler als String
58
    lcd_string("Hello World!");
59
    _delay_ms(2000);
60
    lcd_clear();
61
    lcd_string("Bye World!");
62
      
63
  
64
while(1)
65
{
66
int std=0;
67
int min=0;
68
int sek=0;
69
70
/* Fuehre Aktion aus, wenn Bit Nr. 0 (das "erste" Bit) in PINB gesetzt (1) ist */
71
if ( PINB & (1<<PINB1) ) 
72
{
73
  /* Aktion */
74
  std ++;
75
}
76
77
if ( PINB & (1<<PINB2) ) 
78
{
79
  /* Aktion */
80
  min ++;
81
}
82
83
if ( PINB & (1<<PINB2) ) 
84
{
85
  /* Aktion */
86
  sek ++;
87
}
88
}
89
} // Programmende

Ich weiß gerade nicht wo mir der Kopf steht und vor allem, wie ich 
weitermachen soll.

Ich bitte um Mithilfe.

Vielen Dank
-Basti-

: Verschoben durch Moderator
von troll (Gast)


Lesenswert?

>#warning "F_CPU war noch nicht definiert, wird nun mit 3686400 definiert"
>#define F_CPU 16000000L
Das ist schon mal ein ganz schlechter Anfang. Die beiden Zahlen sollten 
übereinstimmen... Schmeiß diesen Murks raus und definier F_CPU im 
Makefile bzw. in den Projektoptionen.

von troll (Gast)


Lesenswert?

Die Taster solltest du als erstes per Timerinterrupt entprellen, dafür 
gibt es hier im Forum eine ausgereifte Routine von Peter Dannegger 
(Suche fragen!). Was das eigentliche Programm angeht, ich würde es mit 
einer http://www.mikrocontroller.net/articles/Statemachine versuchen...

von Pastor Braune (Gast)


Lesenswert?

Sebastian M. schrieb:
> DDRD = 0xff;          // Setzen aller Pins des Portes B als Output 0b11111111 = 
0xff

und gewöhne dir an die Kommentare zu ändern wenn du etwas änderst !

mfg

von STK500-Besitzer (Gast)


Lesenswert?

Sebastian M. schrieb:
> ich bin ein Maschinenbaustudent und der Meinung das die Elektrotechnik
> in meinem Studiengang generell zu kurz kommt.

Dann wäre die MEchatronik vielleicht besser für dich geeignet.

Zu den anderen Problemen: Guck mal nach "Entprellen".

von Sebastian M. (basti87)


Lesenswert?

Danke für eure schnellen Antworten. Ihr kennt das vielleicht, wenn man 
jede Menge Artikel liest und immer irgendwelche Sachen übernehmt, dann 
ändert usw. Ich glaube ich muss erstmal etwas Struktur reinbringen.

Wisst ihr, wie ich dann den eigendlichen Countdown realisiere? 
Vielleicht so?
1
  if( sek == 0 )
2
  {
3
    sek = 59;
4
    min--;
5
  }
6
  else
7
  sek --;
8
  
9
  if( min == 0 )
10
  {
11
    min = 59;
12
    std--;    
13
  }
14
  else
15
  min --;

Grüße

von spontan (Gast)


Lesenswert?

Die Sekunde 59 gibts gar nicht oder? Zumindest nicht sehr lange.

von Sebastian M. (basti87)


Lesenswert?

spontan schrieb:
> Die Sekunde 59 gibts gar nicht oder? Zumindest nicht sehr lange.

Ich denke schon, guck mal auf deinem Handy.
01:00
00:59
00:58
00:57
...

von Harald W. (wilhelms)


Lesenswert?

spontan schrieb:

> Die Sekunde 59 gibts gar nicht oder?

Das ist nur bei DCF so. :-)
Gruss
Harald

von Sebastian M. (basti87)


Lesenswert?

Sehr geehrte Forum Gemeinde,

ich habe das Ausmaß dieses Projektes falsch eingeschätzt und sehe mich 
gezwungen das Projekt auf die Semesterferien zu verschieben.

Ich bedanke mich für die Zahlreichen Antworten und Hilfestellungen. Ich 
würde mich freuen, wenn wir hier dann in 4 Monaten hier weiter machen 
können, wo wir aufgehört haben.

Freundliche Grüße

Basti

von Karl H. (kbuchegg)


Lesenswert?

Sebastian M. schrieb:
> Sehr geehrte Forum Gemeinde,
>
> ich habe das Ausmaß dieses Projektes falsch eingeschätzt und sehe mich
> gezwungen das Projekt auf die Semesterferien zu verschieben.

Wozu du dich gezwungen sehen solltest ist, erst mal mit noch einfacheren 
Dingen anzufangen.
Auch wenn eine Uhr banal aussieht, schliesslich weiß jeder wie eine Uhr 
funktioniert, so stecken da schon einige Konzepte drinnen, die man 
vorher verinnerlicht haben sollte.

Auch Rom wurde nicht an einem Tag erbaut.

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.