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
Kommentare im Quellcode kosten keinen Cent ;-) Ich sehe beim Counddowncode keine Manipulation der Variablen k. Und wozu brauchst du die for-Schleifen?
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
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
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
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
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
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.