Forum: Compiler & IDEs Multiplexen Küchenuhr


von Christian Möller (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich hab hier ein kleines Problem :)

Es handelt sich um einen Tiny2313, versehen mit 2 gemultiplexten 
7-Segment-Anzeigen, der als Küchenuhr fungieren soll.

Per Taster an PA1 soll die Zeit hochgezählt werden und per PA0 wieder 
runter...an sich kein Problem, zumindest was das hochzählen angeht.
Runterzählen funktioniert nicht, jedenfalls will er die innere Schleife 
nicht abarbeiten (bzw. er tuts, nur interessiert ihn das delay herzlich 
wenig), die Äussere arbeitet wunderbar...
Ich bin mit meinem Latein am Ende, vielleicht kann ja einer von euch mal 
einen Blick auf den Code werfen und sieht irgendwas :)
Möglicherweise hab ich ja nur Tomaten auf den Augen...

vielen Dank

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Kommentare im Quellcode kosten keinen Cent ;-)

Ich sehe beim Counddowncode keine Manipulation der Variablen k. Und wozu 
brauchst du die for-Schleifen?

von Christian Möller (Gast)


Lesenswert?

Ja sorry wegen der fehlenden Kommentare, das war recht schnell 
hingezaubert ;)

k brauch ich im countdown eigentlich nichtmehr, ich verwende es ja nur 
um die Zehner und Einer für die 2 7-Segment-Anzeigen beim Hochzählen zu 
basteln.
Hmmm, ok die Funktion ist nicht direkt ersichtlich...ich hab 2 
7-Segment-Anzeigen (eine für die Zehner und eine für die Einer) 
einstellbar bis 99 Minuten (jaja, 300ms != 1000ms, kommt später), bei 
drücken des Tasters  an PA1 wird jeweils eine Minute addiert...
Sobald ich den Taster an PA0 drücke, soll die Zeit auf "00" 
zurücklaufen, deshalb die for-Schleifen -> Ich habs auch schon mit 
while(j--) etc. versucht, aber das ändert absolut nichts an diesem 
seltsamen Verhalten.

danke nochmal

von Ralf W. (Gast)


Lesenswert?

Die innere Schleife wird mit ca. 3Hz abgearbeitet. Das sind 3 Stellen
in der Sekunde. Das ist schon recht schnell.

Woran merkst du das das Delay nicht stimmt.
Du solltest auch deine Schaltung posten. Welchen Takt verwendest du?


Schau dir mal hier den Artikel Die genaue Sekunde und den Artikel
über Tastenentprellen an.

gruß ralf

von Christian Möller (Gast)


Lesenswert?

Der delay stimmt (oder stimmt nicht), weil er ganz einfach die 
Einer-Stellen nicht runterzählt (DAS ist ja das Problem), er springt 
ganz einfach von z.B. 30 auf 20 (das allerdings in der korrekten Zeit 
von etwa 3s bei dem code)
Die genaue Sekunde ist relativ unwichtig g ob der Tee nun 8min oder 
8.3min zieht ist irrelevant ;)
Tastenentprellen ist auch kein Thema, 300ms oder mehr hat wohl selbst 
der gröbste Grobmotoriker Zeit :)

Grüsse

von Christian Möller (Gast)


Lesenswert?

Achja, nur um die restlichen Fragen noch zu beantworten, der Tiny läuft 
auf 1MHz internem Takt, die Schaltung ist 
http://www.mikrocontroller.net/articles/Bild:Tut_7_Seg_03.gif entlehnt, 
also nix besonderes.
Nur dürfte das alles nicht wirklich im Bezug zur Frage stehen, 
seltsamerweise funtioniert ja das hochzählen problemlos, was die Frage 
nach dem Takt oder der Schaltung an sich überflüssig macht...

nochmals vielen Dank

von Peter D. (peda)


Lesenswert?

Christian Möller wrote:
> Nur dürfte das alles nicht wirklich im Bezug zur Frage stehen,

Ne, da bist Du im Irrtum.
Die Bespiele sollen zeigen, wie man den Programmablauf übersichtlicher, 
besser zu verstehen, besser zu verändern und besser wartbar gestalten 
kann.
Außerdem bieten sie die Grundlagen für größere komplexere Programme, 
damit man nicht immer wieder von Null anfangen muß.


> seltsamerweise funtioniert ja das hochzählen problemlos, was die Frage
> nach dem Takt oder der Schaltung an sich überflüssig macht...

Ja, so ist das mit der Programmierung.

Wenn ein Teil läuft, heißt das noch lange nicht, daß dieser Teil 
fehlerfrei ist oder das überhaupt der Ansatz richtig ist und man nicht 
in einer Sackgasse steckt. Generell sind Programme mit derart riesigen 
Delays (300.000 Befehle) im Ablauf sehr schwer zu beherrschen.


Sogar, wenn scheinbar alles richtig läuft, muß das Programm keineswegs 
fehlerfrei sein. Die Bestrahlungsgeräte, die an bestimmten Tagen die 
Patienten verbrannten, waren sehr lange in Betrieb, ehe der 
Softwarefehler erkannt wurde.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Ich würde das ganze gar nicht mit getrennten Zehner und Einer
Zählern hochziehen, sondern mit einem simplen uint8_t der als
Sekundenzähler fungiert. Lediglich kurz vor der Ausgabe würde ich
diesen uint8_t in Zehner und Einer trennen.

So ungefähr
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <inttypes.h>
4
#include <avr/interrupt.h>
5
6
void my_delay(int ms){
7
  while(ms--)
8
    _delay_ms(1);
9
}
10
11
char leds[] = {0x81, 0xB7, 0xC2, 0x92, 0xB4, 0x98, 0x88, 0xB3, 0x80, 0x90};
12
13
char zehneiner[] = {0x81, 0x81};
14
15
ISR (TIMER0_OVF_vect){
16
  
17
  if(PORTD & (1 << PD5)){
18
19
    PORTB = zehneiner[1];
20
    PORTD &= ~(1 << PD5);
21
    PORTD |= (1 << PD6);
22
23
  }
24
  else {   // ohne Abfrage. was solls den sonnst sein?
25
    PORTB = zehneiner[0];
26
    PORTD &= ~(1 << PD6);
27
    PORTD |= (1 << PD5);
28
  }
29
}
30
31
void print( uint8_t count )
32
{
33
  ZehnerEiner[1] = leds[ count / 10 ];
34
  ZehnerEiner[0] = leds[ count % 10 ];
35
}
36
37
int main(void)
38
{
39
  DDRB = 0xFF;
40
  DDRD = 0xFF;
41
  DDRA = 0x00;
42
  PORTA |= (1<<PA1);
43
  PORTA |= (1<<PA0);
44
  PORTD |= (1 << PD5) | (1 << PD6);
45
  TIMSK |= (1 << TOIE0);
46
  TCCR0B |= (1 << CS01);
47
  
48
  uint8_t Sekunden = 0;
49
  sei();
50
51
  while(42){
52
    // Hochzaehlen
53
    if(!(PINA & (1 << PA1))){
54
      Sekunden++;
55
      print( Sekunden );
56
      my_delay(300);
57
    }
58
59
    if(!(PINA & (1 << PA0))){
60
      while( Sekunden > 0 )
61
        Sekunden--;
62
        print( Sekunden );
63
        my_delay( 1000 );
64
      }
65
    }
66
  }
67
}

Anstatt der delay Geschichte würde ich wahrscheinlich einen Timer
nehmen, der Timer 0 mit seiner bereits vorhandenen ISR würde sich
dazu anbieten, aber das ist deine Sache.

von Peter D. (peda)


Lesenswert?

Stefan "stefb" B. wrote:
> Kommentare im Quellcode kosten keinen Cent ;-)

Aber sie können durchaus Geld wert sein.

Wenn man Sachen kommentiert, kann man schneller erkennen, ob etwas 
richtig ist, oder ob man Bullshit verzapft hat.

Es ist ein großer Irrtum zu glauben, Kommentare sind nur dazu da, damit 
andere den Code verstehen.
Kommentare nützen am meisten einem selber.


Peter

von Peter D. (peda)


Lesenswert?

Karl heinz Buchegger wrote:

>
1
>   else {   // ohne Abfrage. was solls den sonnst sein?
2
>

Es kann durchaus etwas anderes sein, wenn die Initialisung falsch ist.
Und dann käme man auch nie aus dem falschen Zustand heraus.

Es ist aber für fehlertolerante Programmierung von Vorteil, wenn man 
immer einen default-Zweig hat, der sämtliche unberücksichtigten Zustände 
behandelt und das Programm in einen erlaubten Zustand überführt.


Peter

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.