Forum: Mikrocontroller und Digitale Elektronik AVR - if/while werden übersprungen


von Fritz M. (femami)


Lesenswert?

Hallo Zusammen,

im Rahmen eines Hochschulprojekts müssen wir auf einem ATMega32 mit dem 
AVR Studio 4 eine Uhr schreiben, inklusive Datum und Weckfunktion.

Die Compiler-Einstellungen sind auf -0O und -0S, in beiden Einstellungen 
ging es nicht. Auch unser Dozent ist überfragt und somit seid ihr unsere 
letzte Hilfe.

Folgendes steht ganz oben:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include "lcd.h"
4
5
//sprich die 'Standard', die delay und die lcd-Headerfile
6
//auch eine weitere Source-File für das LCD-Display ist eingebunden
7
//alle Variablen wurden als uint8_t udn als globale Variable definiert
Nach Start der Uhr wird der Benutzer aufgefordert das Datum 
einzustellen. Natürlich besteht hier die Problematik mit Schaltjahren 
und die Tagen pro Monat. Dies wurde über die beiden folgenden Funktionen 
realisiert, welche im Laufe des Einstellens auf gerufen werden.
1
// Funktion für Schaltjahr
2
uint8_t leapyeartester (uint8_t year)
3
{
4
  if((year%400==0) && !((year%100==0) && !(year%4==0)))
5
    return 1;
6
  else
7
    return 0;
8
}
9
10
//Funktion für days per month
11
uint8_t dpmtester(uint8_t monat, uint8_t jahr)
12
{
13
14
  uint8_t array_dpm[14] = {  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
15
16
  if (monat == 2)
17
  {
18
    // Februar: Schaltjahr unterscheiden
19
    if (leapyeartester(jahr)==1)
20
      return 29;
21
    else
22
      return 28;
23
  }
24
25
  if ((monat >= 1) && (monat <= 12))
26
    return array_dpm[monat];
27
  else
28
  {
29
    return 0;
30
  }
31
}
Das Einstellen der Monate findet in folgender Funktion statt, welche 
soweit auch funktioniert:
1
void setMonth ()
2
{
3
  y1=5;                  // Monate-Einer -- Schema siehe oben
4
  y2=0;
5
  mon1=-1;
6
  lcd_gotoxy(0,0);
7
  lcd_puts("Monat Einer*****");
8
  lcd_gotoxy(y1,1);
9
  lcd_putc(y2+0x30);
10
11
  while (bit_is_set(PIND, PD3));
12
  while (bit_is_clear(PIND, PD3))
13
    for (mon1=0;mon1<10 && bit_is_clear(PIND, PD3);)
14
    {
15
    y2=mon1+0x30;
16
    lcd_gotoxy(y1,1);
17
    lcd_putc(y2);
18
    _delay_ms(350);
19
    mon1++;
20
    }
21
22
  y1=4;                  // Monate-Zehner -- Schema siehe oben
23
  y2=0;
24
  mon2=-1;
25
  lcd_gotoxy(0,0);
26
  lcd_puts("Monat Zehner****");
27
  lcd_gotoxy(y1,1);
28
  lcd_putc(y2+0x30);
29
30
  if(mon1>3)                // wenn März bis September
31
  {
32
    y2=0+0x30;
33
    lcd_gotoxy(y1,1);
34
    lcd_putc(y2);
35
  }
36
  else                  // sonst Wahl des Zehner-Monats
37
  {
38
    while (bit_is_set(PIND, PD3));
39
    while (bit_is_clear(PIND, PD3))
40
      for (mon2=0;mon2<2 && bit_is_clear(PIND, PD3);)
41
      {
42
      y2=mon2+0x30;
43
      lcd_gotoxy(y1,1);
44
      lcd_putc(y2);
45
      _delay_ms(350);
46
      mon2++;
47
      }
48
  
49
  }
50
  // Berechnen des Monats als Integer
51
  month_complete = ((mon2*10) + mon1);
52
}

Das Problem ist nun, dass wir nach Einstellen des Monats überprüfen 
wollten, ob 00 eingegeben wurde. Falls ja, soll die Funktion erneut 
aufgerufen werden, um das ganze korrigieren zu können. Wir hatten dies 
mit einer do-while, while und einer if-Probiert. Alle drei Möglichkeiten 
werden  entweder komplett ignoriert oder es blieb in der Schleife 
hängen.

Das Ganze sah so aus:
1
if(month_complete == 0)
2
    setMonth();
oder
1
do { setMonth();} while(month_complete == 0);

Beim Einstellen der Tage gibt es dann genau dasselbe Problem: es bleibt 
hängen oder die Bedingung wird ignoriert.


Ich hoffe ich hab alle Infos, die ihr braucht, und alles verständlich 
beschrieben. Wenn nicht, meldet euch einfach.

Ganz lieben Dank,

fimami!

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Fritz Müller schrieb:

> uint8_t leapyeartester (uint8_t year)
> {
>   if((year%400==0) && !((year%100==0) && !(year%4==0)))

Und da sieht Dein Dozent keinen Fehler? Hmm...

vlg

Timm

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Fritz Müller schrieb:

> Ich hoffe ich hab alle Infos, die ihr braucht

Nein.  Das sind nur Schnipsel.  Es ist nicht klar, wo und wie die
darin benutzten Variablen deklariert sind.

Schlechter Stil ist es obendrein, denn offenbar wird selbst die
popeligste lokale Variable irgendwo „weit weg“ global deklariert.

Eine Deklaration der Form
1
void foo();

ist in C etwas anderes als eine der Form
1
void foo(void);

(In C++ sind beide gleich.)  Erstgenannte Form sollte man sich in C
grundsätzlich gar nicht erst angewöhen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Timm Reinisch schrieb:
> Und da sieht Dein Dozent keinen Fehler? Hmm...

Wer durch diese negiert-negierte Logik noch durchsteigt, gewinnt
einen Preis. :-)

von Karl H. (kbuchegg)


Lesenswert?

Fritz Müller schrieb:

> Ich hoffe ich hab alle Infos, die ihr braucht

Nicht wirklich.
EIn komplettes testbares Programm wäre besser.

Lasst euch halt mal den Zahlenwert der Variablen wo ausgeben. Dann wisst 
ihr exakt was da drinnen steht.

PS: Das ganze wäre wesentlich einfacher, wenn ihr nicht nach Einern und 
Zehnern trennen würdet. Bei 2-stelligen Zahlen, gerade in dem Bereich 
wie sie bei Uhren vorkommen, lohnt das nicht wirklich. Da ist das 
rumfummeln mit Einern und Zehnern sowohl für einen Benutzer als auch im 
Programm komplizierter, als wenn bei den Monaten einfach die Zahlen von 
1 bis 12 durchlaufen. Eine ordentliche Zahlenausgabefunktion, die 
2-stellige Zahlen an eine bestimmte Position am LCD ausgeben kann und 
nicht dieses Gefrickel wie da im Code und die Sache ist zu 70% gegessen. 
Und der Codelänge würde das auch zugute kommen. Denn gerade bei einer 
Uhr braucht man so eine Funktion an allen Ecken und Enden. Genauso wie 
eine ordentliche Tasten-Funktion und nicht dieses Pin_set Pin_Clear 
Gefrickel von da oben.

von Fritz M. (femami)


Angehängte Dateien:

Lesenswert?

Hier mal das komplette Programm. Mir ist bewusst, dass es teilweise noch 
nicht vollständig ist. Im Prinzip geht es nur um den Teil bis "Uhr 
stellen".

Der leapyeartester müsste aber eigentlich gehen, das ist eine Ausnahme 
mit einer Ausnahme von der Ausnahme :D Lass mich gerne eines besseren 
belehren.

Das mit dem Haufen an globalen Variablen war im Endeffekt nur eine 
Notfalllösung, da wir dachten es gäbe u.U. Probleme mit 
Gültigkeitsbereichen.

lg und vielen vielen Dank für die schnellen Antworten, bin zwar noch 
dezent überfordert aber vielleicht legt sich das ja noch :)

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Jörg Wunsch schrieb:
> Timm Reinisch schrieb:
>> Und da sieht Dein Dozent keinen Fehler? Hmm...
>
> Wer durch diese negiert-negierte Logik noch durchsteigt, gewinnt
> einen Preis. :-)

meinst Du meinen Satz oder die If-Anweisung?

Ich hätte halt Bedenken, ob man einen uint8_t wirklich sinnvoll modulo 
400 rechnen kann.
Habe ich da jetzt einen Denkfehler? Doch wohl nicht?

Vlg
 Timm

von Fritz M. (femami)


Lesenswert?

Timm Reinisch schrieb:
> Ich hätte halt Bedenken, ob man einen uint8_t wirklich sinnvoll modulo
> 400 rechnen kann.
> Habe ich da jetzt einen Denkfehler? Doch wohl nicht?


Wir hatten jetzt ca 18 Stunden Microcontroller, davon waren 50% unnütz 
für unseren Code. Also wenn du das sagst, glaub ich dir das :) Was wäre 
denn eine Alternative?

von Ulrich P. (uprinz)


Lesenswert?

Das ist jetzt aber nicht euer Ernst, oder?
1
uint8_t leapyeartester (uint8_t year)
2
{
3
  if((year%400==0) && !((year%100==0) && !(year%4==0)))
4
    return 1;
5
  else
6
    return 0;
7
}

year ist uint8_t und ihr mach damit modulo 400?
Es ist schon klar, dass year ab 256 etwas überfordert ist...

Gruß, Ulrich

von Karl H. (kbuchegg)


Lesenswert?

Da steht aber
1
  if (mon2 ==0)
2
  setMonth();




Euer Code ist FURCHTBAR!
Das da keiner mehr durchblickt wundert mich nicht.

Macht mal eure Hausafgaben und schreibt euch für immer wiederkehrende 
Teile eigene Funktionen! Zb die Ausgabe von 2-stelligen Zahlen ist so 
ein immer wieder kehrender Baustein. Und da finden sich noch viele 
andere Dinge.

Die Monatseinstellung mit einem ordentlichen Unterbau an Funktionen bzw. 
Funktionalität kann so einfach sein wie
1
uint8_t setMonth( uint8_t month )
2
{
3
  lcd_text( 0, 0, "Monat " );
4
  lcd_number( 0, 6, month );
5
6
  while( !key_presses( 1 << READY_KEY ) )
7
  {
8
    if( key_pressed( 1 << USER_KEY ) || key_repeat( 1 << USER_KEY ) )
9
    {
10
      month++;
11
      if( month == 13 )
12
        month = 0;
13
14
      lcd_number( 0, 6, month );
15
    }
16
  }
17
18
  return month;
19
}

Und da braucht man noch nicht mal testen, was der Benutzer eingegeben 
hat, weil er gar keine Möglichkeit hat, einen ungültigen Monat 
einzugeben.

von Rene H. (Gast)


Lesenswert?

Fritz Müller schrieb:
> Wir hatten jetzt ca 18 Stunden Microcontroller, davon waren 50% unnütz
> für unseren Code. Also wenn du das sagst, glaub ich dir das :) Was wäre
> denn eine Alternative?

Was die Jungs dir damit sagen wollen, ist, das uint8_t (1 Byte) einen 
max. Wert von 255 haben kann.
Ein module 400 darauf macht nun wirklich keinen Sinn. Was soll den genau 
in Year genau stehen? (ich habe mir nicht den ganzen Code durchgesehen).

Grüsse,
R.

von Peter II (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Und da braucht man noch nicht mal testen, was der Benutzer eingegeben
> hat, weil er gar keine Möglichkeit hat, einen ungültigen Monat
> einzugeben.

doch mit diesen code schafft man es eine 0 einzugeben:

müsste doch bestimmt

if( month == 13 )
   month = 1;

sein.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> void foo();
>
> sollte man sich in C grundsätzlich gar nicht erst angewöhen.

Hilfreich sind dabei die Optionen

 -Werror=strict-prototypes
 -Werror=missing-prototypes

Bleibt die Frage, warum tolle GUIs wie AVR Studio diese nicht setzen...?

von Ulrich P. (uprinz)


Lesenswert?

Jetzt haben alle "Alte Hasen" den Thread gleichzeitig gesehen ;)

von Fritz M. (femami)


Lesenswert?

Ja das macht irgendwie Sinn..sorry, muss geändert werden.
Aber das kann ja nicht Grund für das Problem sein, das leapyeartester 
wird ja zu dem Zeitpunkt noch gar nicht aufgerufen.

kbuchegg..ja das mag sein aber dazu fehlt es uns einfach an Übung und am 
nötigen "Wortschatz". Dein Vorschlag klingt natürlich irgendwie besser 
und auch mehr auf den Punkt gebracht, jedoch übertrifft das unsere 
bisherigen Kenntnisse um einiges.

von Unwissend (Gast)


Lesenswert?

Fritz Müller schrieb:
> Das Ganze sah so aus:
>
1
if(month_complete == 0) 
2
>     setMonth();
> oder
>
1
do { setMonth();} while(month_complete == 0);
>
> Beim Einstellen der Tage gibt es dann genau dasselbe Problem: es bleibt
> hängen oder die Bedingung wird ignoriert.

do_while:
wenn "setMonth()" "month_complete" nicht ändert, rutscht er einmal durch 
die Schleife. Vor_ oder _in setMonth muss month_complete also auf !=0 
gesetzt werden und falls "00" eingegeben wird auf =0 gesetzt werden.

if:
month_complete muss vorher !=0 sein, des weiteren müsst noch ne Schleife 
drumherum mit Abbruchbedingung =0

von Rene H. (Gast)


Lesenswert?

Hallo Fritz,

ich habe mal drüber geschaut. Generell solltet ihr nochmals durch den 
Code (wenn ihr aus Zeitnot/druck nicht alles nochmals schreiben wollt) 
und euch überlegen, welche Maximalwerte die Variabeln annehmen können.

Beispiel:
1
uint8_t year_complete=0;        // Jahr als Integer

später:
1
  // Berechnen der Jahreszahl als Integer
2
  year_complete = (2000 + (j2*10) + j1)

year_complete wrd somit schon mal grösser wie 2000 ==> uint16_t nehmen.

Grüsse,
R.

von Fritz M. (femami)


Lesenswert?

Im Prinzip haben wir noch knapp 3 Wochen Zeit, jedoch ist Semesterende 
und es ist nicht die einzige praktische Arbeit, welche abgegeben werden 
muss - ganz abgesehen von den Klausuren.

Ihr habt uns auf jeden Fall schonmal sehr geholfen!

von Lötlackl *. (pappnase) Benutzerseite


Lesenswert?

1
// Funktion für Schaltjahr 
2
uint8_t leapyeartester (uint8_t year)
3
{                       ^^^^^^^
4
  if((year%400==0) && !((year%100==0) && !(year%4==0)))
5
    return 1;
6
  else
7
    return 0;
8
}
Man, da gibts ja einen Haufen zu korrigieren.

Das da habe ich mal irgendwo in einem Codefetzen von Jörg Wunsch 
gefunden.
1
/*
2
 * alle 4 jahre ausser das jahr ist durch 100 teilbar
3
 *  aber trotzdem wenn durch 400 teilbar.
4
 */
5
static inline uint8_t isLeapYear(uint16_t year) {
6
  return((((year % 4 ) == 0) && ((year % 100) != 0)) || ((year % 400) == 0));
7
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

** Lötlackl schrieb:
> Das da habe ich mal irgendwo in einem Codefetzen von Jörg Wunsch
> gefunden.

Wirklich von mir?  Kann ich mich gar nicht mehr erinnern. ;-)

Tststs, mittlerweile ist in der avr-libc eine total umfangreiche
time-Bibliothek mit drin, die würde natürlich derartige „Gurken“
gleich von vornherein vermeiden.  Gibt's aber noch keinen Release
davon (ja, ich weiß, ist lange überfällig).

von Felix P. (fixxl)


Lesenswert?

Fritz Müller schrieb:
> Der leapyeartester müsste aber eigentlich gehen, das ist eine Ausnahme
> mit einer Ausnahme von der Ausnahme :D Lass mich gerne eines besseren
> belehren.

Setz doch mal das Jahr 2012 - nachdem die Jahreszahl von 8 auf 16bit 
erweitert wurde - ein, das ja zweifelsfrei ein Schaltjahr war:
2012%400 = 12 --> Bedingung gibt 0 zurück und damit wird der ganze 
Ausdruck unabhängig vom Ausdruck hinter dem && zu 0, weil 0 && x = 0.

Die Bedingung für ein Schaltjahr heißt: (Jahreszahl muss durch 4 teilbar 
sein UND nicht durch 100) ODER (durch 400). Die Klammern stehen da rein 
zufällig ;-).

Nachtrag: War wohl zu langsam...

von Lötlackl *. (pappnase) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Wirklich von mir?  Kann ich mich gar nicht mehr erinnern. ;-)

Man, bin ich doof. Der Gute, von dem ich klaute, hieß Martin Thomas. 
Gerade noch mal nachgesehen. :-(

von spess53 (Gast)


Lesenswert?

Hi
1
uint8_t array_dpm[14] = {  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

Mein Delphi würde das anmeckern.

MfG Spess

von Fritz M. (femami)


Lesenswert?

> Mein Delphi würde das anmeckern.

Mein Studio4 meckert eben nur über bisher nicht benutzte Variablen, 
sonst ist es ruhig -.-

von Markus M. (mark_m)


Lesenswert?

Euer Leerkörper hat euch auch strikt verboten, unter Androhung von 
Punktabzug, nie nicht auf keinen Fall vor der Umsetzung mit der 
Programmiersprache ein

Nassi-Shneiderman-Diagramm

oder einen

Programmablaufplan

anzufertigen.

Der Arbeitsmarkt freut sich schon auf solch hoch qualifizierte 
Fachkräfte. Wenigsten sind die dann billig zu haben.

Grüsse

von Fritz M. (femami)


Lesenswert?

Ablaufplan steht, aber bringt uns in diesem Fall auch nicht weiter.

Das Kernproblem ist ja, dass die Schleifen und if-Anweisungen in keinem 
Fall richtig durchgeführt werden. Einzig while(1) scheint zu 
funktionieren.

Das Komische: nach dem compilieren und 'rüberschicken per Khazama hat es 
einige Male perfekt funktioniert. Nach einem einfachen Reset ging es 
erneut nicht.

von Markus M. (mark_m)


Lesenswert?

Wenn das Programm das Abbild des Ablaufplans ist glaub ich es unbesehen. 
:-P

Grüsse

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

spess53 schrieb:

>
1
> uint8_t array_dpm[14] = {  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 
2
> 30, 31 };
3
>
>
> Mein Delphi würde das anmeckern.

C ist auch nicht Pascal. :-)  Wofür allerdings das überflüssige
Element überhaupt erst allokiert wird, bleibt ein Rätsel.  Element 0
kann man natürlich genauso einsparen, indem man dann beim Zugriff
jeweils 1 abzieht.

Da ist das Array nun schon mal eine lokale Variable, dann wird sie
aber auch noch als Speicherklasse “auto” angelegt, was in diesem
Falle wenig sinnvoll ist … “static” wäre hier angebrachter, und
eigentlich kann man sich auch gleich “static const” für sowas
angewöhnen.

von Godi S. (godi22)


Lesenswert?

Jörg Wunsch schrieb:
> Eine Deklaration der Form
> void foo();
>
> ist in C etwas anderes als eine der Form
> void foo(void);

Wo liegt denn genau der Unterschied?
Ich habe irgendwas gefunden bezüglich alten Stil aber nicht genau 
herausgefunden wo der Unterschied ist.

von Rene H. (Gast)


Lesenswert?

@Fritz

Setze doch das alles mal um, zu was dir hier geraten wurde. Dann bring 
etwas Leserlichkeit/Ordnung in den Code. Zum Beispiel:

statt:
1
    y2=t2+0x30;

so:
1
    y2 = t2 + 0x30;

Vor if/while was auch immer eine Leerzeile etc. (schau dir Beispielcode 
an).

Wenn Du dann immer noch Probleme hast, bekommst Du hier sicher 
Hilfestellung auf konkrete Fragen (und selbstverständlich auch den einen 
oder anderen unsachlichen Kommentar, etwas Blutgeld für die Hilfe muss 
man in Kauf nehmen ;-)).

Grüsse,
René

von Felix P. (fixxl)


Lesenswert?

godi S. schrieb:
> Jörg Wunsch schrieb:
>> Eine Deklaration der Form
>> void foo();
>>
>> ist in C etwas anderes als eine der Form
>> void foo(void);
>
> Wo liegt denn genau der Unterschied?
> Ich habe irgendwas gefunden bezüglich alten Stil aber nicht genau
> herausgefunden wo der Unterschied ist.

void foo() ist eine Funktion, deren Übergabeparameter nicht definiert 
sind. Man kann ihr also irgendwas übergeben.

void foo(void) ist eine Funktion, die laut Definition keine 
Übergabeparameter besitzt. Übergibt man ihr etwas, meckert der Compiler.

von Karl H. (kbuchegg)


Lesenswert?

Rene H. schrieb:
> @Fritz
>
> Setze doch das alles mal um, zu was dir hier geraten wurde. Dann bring
> etwas Leserlichkeit/Ordnung in den Code. Zum Beispiel:
>
> statt:
>
>
1
>     y2=t2+0x30;
2
>
>
> so:
>
>
1
>     y2 = t2 + 0x30;
2
>

Noch besser
1
  y2 = t2 + '0';

Aber eigentlich sollte das Ausgeben einer 2-stelligen Zahl sofort mal in 
eine Funktion verschwinden. Schon alleine das würde den Code über den 
Daumen um mindestens 30% schrumpfen lassen.

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> Karl Heinz Buchegger schrieb:
>> Und da braucht man noch nicht mal testen, was der Benutzer eingegeben
>> hat, weil er gar keine Möglichkeit hat, einen ungültigen Monat
>> einzugeben.
>
> doch mit diesen code schafft man es eine 0 einzugeben:
>
> müsste doch bestimmt
>
> if( month == 13 )
>    month = 1;
>
> sein.

Mist. Punkt für dich.

von Karl H. (kbuchegg)


Lesenswert?

> Das Kernproblem ist ja, dass die Schleifen und if-Anweisungen in keinem Fall 
richtig durchgeführt werden.

Das Kernproblem ist, dass in diesem Codewust irgendwo ein Hund steckt, 
den man aber ob der schieren Code-Übermacht nicht findet. Der Code 
erschlägt einen förmlich.

Den muss man jetzt erst mal ein wenig strukturieren und in kleinere 
Abschnitte aufteilen - sprich in Funktionen gruppieren, die überschaubar 
sind und bei denen man durch blosses hinsehen schon sagen kann: das 
passt.

von Fritz M. (femami)


Lesenswert?

Ist in Arbeit. Danke euch bis hierhin!

von Fritz M. (femami)


Angehängte Dateien:

Lesenswert?

Hier mal die verbesserte Version..zumindest bis Datum und Uhrzeit 
eingestellt sind. Hatte leider keinen Compiler zur Hand, aber dürfte 
schonmal besser sein als vorhin :)

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

** Lötlackl schrieb:
1
return((((year % 4 ) == 0) && ((year % 100) != 0)) || ((year % 400) == 0));

Da komm ich ja vor lauter Klammernzählerei zu nichts anderem mehr. :-)

So ist es leichter verständlich – finde ich:
1
return year%4==0 && year%100!=0 || year%400==0;

Richtig, in diesem Fall ist jede der 16 (!) Klammern überflüssig.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Fritz Müller schrieb:
> Hier mal die verbesserte Version..zumindest bis Datum und Uhrzeit
> eingestellt sind. Hatte leider keinen Compiler zur Hand, aber dürfte
> schonmal besser sein als vorhin :)

Ich geb zu, ich hab mir nur eine Zeile angeschaut:
1
if((year%400==0) && !((year%100==0) && !(year%4==0)))

Teste die bitte mal mit verschiedenen Jahreszahlen aus. Bei 2000 
stimmts, bei 2004 stimmts nicht mehr. Da ist noch ein Knoten in der 
Formel...

von Fritz M. (femami)


Angehängte Dateien:

Lesenswert?

stimmt. dann hat ich das falsch in Erinnerung. Dann versuch ich mich mal 
an euren Vorschlägen :)

Danke!

edit: geht! Danke an alle, welche das korrigiert hatten und sorry, dass 
ich da nicht einsichtig war ;-)

von Karl H. (kbuchegg)


Lesenswert?

Der Teil hier
1
  lcd_gotoxy(0,0);            // Ausgabeposition festlegen
2
  lcd_puts("-----Minuten----");      // String ausgeben
3
4
  while (bit_is_set(PIND, PD3));      // Arrettieren solange nichts gedrückt
5
  
6
  while (bit_is_clear(PIND, PD3))      // Bei Tastendruck...
7
    for (m = 0;(m < 60) && 
8
    bit_is_clear(PIND, PD3);)
9
    {                  
10
    showNumber(12,1,m);          
11
    _delay_ms(350);
12
    m++;                
13
    }

(ich hab jetzt mehr zufällig die Minuten herausgegriffen)

... ist für die Eingabe von Zahlen immer der gleiche. Einzig die 
Vergleichszahl für die höchste zulässige Zahl ist immer anders.

-> Ab in eine FUnktion mit der kompletten Funktionalität
1
uint8_t getNumber( const char* text, uint8_t x, uint8_t y, uint8_t minimum, uint8_t maximum )
2
{
3
  uint8_t number;
4
5
  lcd_gotoxy(0,0);            // Ausgabeposition festlegen
6
  lcd_puts( text );
7
8
  while (bit_is_set(PIND, PD3));      // Arrettieren solange nichts gedrückt
9
  
10
  while (bit_is_clear(PIND, PD3))      // Bei Tastendruck...
11
  {
12
    for (number = minimum; (number <= maximum) && bit_is_clear(PIND, PD3);)
13
    {                  
14
      showNumber(x,y,number);          
15
      _delay_ms(350);
16
      number++;                
17
    }
18
  }
19
20
  return number;
21
}


damit magert deine ganze Eröffnungssequenz ab zu
1
  ....
2
  _delay_ms(2000);            // Verzögerung von 2 Sekunden
3
  lcd_clrscr();              // LCD clearen
4
  lcd_gotoxy(9,1);            // Ausgabeposition festlegen      
5
  lcd_puts=("00:00:00");          // Startanzeige
6
    
7
  j = getNumer( "------Jahre-----", 15, 1, 0, 25 );
8
  year_complete = 2000 + j;
9
  
10
  mon = getNumber( "-----Monate-----", 12, 1, 1, 12 );
11
  dpmresult = dpmtester (mon, year_complete);      // Berechnen der Days per Month und speichern in Variable
12
  
13
  t = getNumber( "------Tage------", 9, 1, 1, dpmresult + 1 );
14
15
  /*+++++++++++++++++++++++++++++
16
  -----------UHR STELLEN---------
17
  +++++++++++++++++++++++++++++*/
18
  lcd_clrscr ();              // LCD clearen
19
  lcd_gotoxy(0,0);            // Ausgabeposition festlegen
20
  lcd_puts("Uhr stellen");        // String ausgeben
21
  lcd_gotoxy(0,1);            // Ausgabeposition festlegen
22
  lcd_puts("mit Taste S1");        // String ausgeben
23
24
  _delay_ms(2000);            // Verzögerung von 2 Sekunden
25
  lcd_clrscr();              // LCD clearen
26
  lcd_gotoxy(9,1);            // Startanzeige
27
  lcd_puts=("00:00:00");
28
    
29
  m = getNumber( "-----Minuten----", 12, 1, 0, 59 );
30
  h = getNumber( "-----Stunden----" , 9, 1, 0, 24 );


und du hast den Vorteil, dass du den kompletten Bereich, wie 
Benutzereingaben eigentlich funktionieren, an einer Stelle beisammen 
hast. Wenn dir die Systematik nicht mehr gefällt, dann änderst du sie an 
EINER Stelle ab und ALLE Eingaben funktionieren dann automatisch alle 
gleich nach deinem neuen Schema.

von Fritz M. (femami)


Lesenswert?

Hehe..ja das dacht ich mir anfangs auch - wenn ich schon dabei bin. War 
nur ehrlich gesagt zu faul nach dem ganzen Informatik heute (3 Stunden 
verzweifelt vor AVR Studio gesessen, 2 weitere nur halbwegs verzweifelt 
und dann noch 2 Stunden Java-GUI...bei dem schönen Wetter;-))

Vielen Dank! Das macht doch gleich viel mehr her!
Würde ja sagen "hast was gut", aber ich wüsste nicht wie ich mich 
revanchieren sollte.

Sonst? Im Vergleich zum Anfang ein Tick besser?


p.s.
müsste folgendermaßen heißen oder?
h = getNumber( "-----Stunden----" , 9, 1, 0, 23 );

von Rene H. (Gast)


Lesenswert?

Hallo Fritz,

ich habe den Code nur kurz angeschaut, sauber, um Welten besser. Noch 
etwas zur Lesbarkeit, versuche Sequenzblöcke optisch abzuheben. Also 
auch nach einem if (xxx) {  } eine Leerzeile.

Vieles wurde sonst bereits gesagt (ich habe morgen ein Interview und 
kann mich jetzt fachlich nicht reinhängen).

Sourcecode ist nie einfach funktional, er muss auch optisch ohne ihn zu 
verstehen etwas hergeben. Man schaut ihn an und es sieht einfach 
aufgeräumt aus.

Ach noch was, bei einem Funktionsaufruf, nach dem Komma immer ein Space, 
also Func(a, b).

Grüsse,
R.

von Fritz M. (femami)


Lesenswert?

Danke dir!
Werde im Laufe der nächsten Tage noch den Wecker einbauen, das sollte 
aber vermutlich keine Komplikationen mehr bereiten und es dann mal auf 
den Atmega hauen.

Wünsch dir für morgen viel Erfolg und Spaß beim Interview!
Ich verabschiede mich für heute auch!

lg

von Rene H. (Gast)


Lesenswert?

Fritz Müller schrieb:
>
> Vielen Dank! Das macht doch gleich viel mehr her!
> Würde ja sagen "hast was gut", aber ich wüsste nicht wie ich mich
> revanchieren sollte.
>

Die Hilfestellungen von Karl-Heinz sind hier im Forum beinahe Legendär. 
Er macht das einfach so. Ich bin längst (Jahre...) beeindruckt ob dem 
Engagement.

Ein Kompliment an der Stelle an die Moderatoren hier, das ist nicht 
selbstverständlich in der Ausführlichkeit!

Grüsse,
René

von Fritz M. (femami)


Lesenswert?

Rene H. schrieb:
> Ein Kompliment an der Stelle an die Moderatoren hier, das ist nicht
> selbstverständlich in der Ausführlichkeit!

Dem muss ich mich gleich anschließen. Auch natürlich an den Rest ein 
herzliches Danke! Weiß das echt zu schätzen. Wenn jemand Hilfe in 
HTML/CSS benötigen sollte, kann ich ja vielleicht was gutes tun ;-D

von Holger W. (holgerw)


Lesenswert?

Rene H. schrieb:
> Die Hilfestellungen von Karl-Heinz sind hier im Forum beinahe Legendär.
> Er macht das einfach so. Ich bin längst (Jahre...) beeindruckt ob dem
> Engagement.
>
> Ein Kompliment an der Stelle an die Moderatoren hier, das ist nicht
> selbstverständlich in der Ausführlichkeit!

dem möchte ich mich auch mal anschließen !
Manchmal lese ich ich Threads durch und mitten im Text denk ich, so wie 
das erklärt wird, kann es nur Karl-Heinz sein und meist bestätigt sich 
das dann auch.
Hat mir schon oft geholfen, vielen Dank dafür.

Holger

von Norbert (Gast)


Lesenswert?

Fritz Müller schrieb:

> Die Compiler-Einstellungen sind auf -0O und -0S, in beiden Einstellungen
> ging es nicht. Auch unser Dozent ist überfragt und somit seid ihr unsere
> letzte Hilfe.

Möglicherweise weil die Einstellungen -O0 und -Os lauten?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

In diesem Fall zählt die zuletzt gegebene Option, d.h. -Os.

von Fritz M. (femami)


Lesenswert?

Hat jemand eine Idee, warum mein Compiler mit

lcd_puts("Uhr     00:00:00");

kein Problem hat, aber  dafür mit folgendem?

lcd_puts("00:00:00");

Gibt's da Probleme wegen der '0' am Anfang?

Lg

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Nein.

von Rene H. (Gast)


Lesenswert?

Was sagt den der Compiler?

von Fritz M. (femami)


Lesenswert?

Kann ich nachher sagen, hab grad kein Compiler mehr zur Hand..

von Fritz M. (femami)


Lesenswert?

Sorry, Problem gefunden. Im Code sah's in Wirklichkeit so aus:

lcd_puts = ("00:00:00");

Der Zuweisungs-Operator ist da fehl am Platz.

von Fritz M. (femami)


Lesenswert?

Ich dachte ich melde mich zum Schluss nochmal.

Programm lief soweit, einige Kleinigkeiten mussten noch geändert werden. 
Jetzt läuft alles, wie es von Anfang an geplant war. Besteht auf jeden 
Fall Motivation da weiter zu machen und mich auch weiterhin damit zu 
beschäftigen.

Lg das Team

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.