Forum: Mikrocontroller und Digitale Elektronik AVR - Mal wieder ein Wecker


von Flori (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
ich versuche mich derzeit an einem Wecker, da ich etwas sinnvolles mit 
einer Echtzeituhr anstellen möchte:)
Die Uhrzeit steht mittlerweile auf meinem LCD Display und ich denke,dass 
ich das mit dem "Alarm einstellen" hinbekomme, aber momentan tappe ich 
völlig im Dunkeln, was den Vergleich von Uhrzeit und Alarm angeht.
Ungefähr so:
if (Alarmstunde == AktuelleStunde)
{
if (Alarmminute == AktuelleMinute)
{ //Alarm}
}

Ich habe hier einige Threads gefunden, allerdings steige ich da nicht 
ganz durch und deshalb bitte ich direkt um Hilfe :)
Mein Code habe ich im Dateianhang beigefügt.
Mit freundlichen Grüßen Flori

von Teplotaxl X. (t3plot4x1)


Lesenswert?

1
if (Alarmstunde == AktuelleStunde)
2
{
3
if (Alarmminute == AktuelleMinute)
4
{ //Alarm}
5
}
lässt sich vereinfachen
1
if (Alarmstunde == AktuelleStunde && Alarmminute == AktuelleMinute)
2
{ //Alarm}
3
}
PS: Code als *.c anhängen, dann geht auch die Syntaxhervorhebung

von Flori (Gast)


Angehängte Dateien:

Lesenswert?

Ok hier nochmal der Code in C.

von Emperor_L0ser (Gast)


Lesenswert?

Moin,
die zweite Variante ist zwar etwas besser lesbar, allerdings würde ich 
davon ausgehen, dass der gleiche ASM Code daraus generiert wird.

mfg Emperor_L0ser

von Flori (Gast)


Lesenswert?

Ich glaube man hat mich etwas falsch verstanden bzw ich habe mich falsch 
ausgedrückt^^
Ich wollte eigentlich wissen, wie ich die Variable "Aktuelle Stunde" bzw 
"Aktuelle Minute" definieren kann. Deshalb auch der Code.
Gruß

von karlheinz (Gast)


Lesenswert?

was meinst du?

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:
> Ich glaube man hat mich etwas falsch verstanden bzw ich habe mich falsch
> ausgedrückt^^
> Ich wollte eigentlich wissen, wie ich die Variable "Aktuelle Stunde" bzw
> "Aktuelle Minute" definieren kann. Deshalb auch der Code.
> Gruß

Fang mal damit an, diese Funktion ...
1
void rtcSendTimeLcd()
2
{
3
   lcdGoto(1,1);
4
   rtcSendBcdLcd(rtcGetHour());
5
   rtcWaitMs(20);
6
   lcdWrite(":");
7
   rtcSendBcdLcd(rtcGetMinute());
8
   rtcWaitMs(20);
9
   lcdWrite(":");
10
}

... in 2 Funktionen aufzuteilen. Im Moment erfüllt diese Funktion 2 
Aufgaben in einem: Sie holt die aktuelle Uhrzeit und gibt sie am LCD 
aus. Das unterteilst du in 2 getrennte Funktionen:
* Eine die die aktuelle Uhrezeit holt und sie in 2 Variablen (Stunde, 
Minute) ablegt
* Eine zweite Funktion, die die aktuelle Uhrezeit aus diesen Variablen 
ausgibt.

Damit hast du dann automatisch die aktuelle Zeit auch in einer Form 
vorliegen, so dass du sie weiterverarbeiten (zb. in Form von Abfragen 
auf einen speziellen Zeitpunkt) kannst.


Edit:
Und fang an, deinen Code vernünftig einzurücken. Das ist kein Luxus, 
kann aber ungemein hilfreich bei Fehlersuche sein.

...
1
main()
2
{
3
      DDRB = 0xFF;  // Ausgang
4
      PORTB = 0x00; //
5
      
6
  int alrm = 0; // 0 = kein Alarm  | 1 = Alarm
7
8
   init();   //
9
   while (true)    // Mainloop-Begin
10
   {
11
   if (alarm == 1)
12
   {
13
   sbi (PORTB,0);//Licht an  / Ton an
14
  }
15
   else
16
   {
17
   rtcSendTimeLcd();
18
   }
19
   
20
   } // Mainloop-Ende
21
}

ist keine vernünftige Einrückung, weil man die Struktur nicht erkennen 
kann.

Das hier
1
main()
2
{
3
  DDRB = 0xFF;  // Ausgang
4
  PORTB = 0x00; //
5
      
6
  int alrm = 0; // 0 = kein Alarm  | 1 = Alarm
7
8
  init();   //
9
  while (true)    // Mainloop-Begin
10
  {
11
    if (alarm == 1)
12
    {
13
      sbi (PORTB,0);//Licht an  / Ton an
14
    }
15
    else
16
    {
17
      rtcSendTimeLcd();
18
    }
19
   
20
  } // Mainloop-Ende
21
}

ist eine vernünftige Einrückung. Dort kann man sehr gut erkennen, wo ein 
Block beginnt und wo er wieder endet, ohne dass man { und } abzählen 
muss, bzw. auf Kommentare (die meistens sowieso nicht stimmen) vertrauen 
muss um das Ende eines Blocks wiederzufinden. Die jeweils schliessende } 
steht genau unter der öffnenden { und der Blockinhalt ist (in diesem 
Fall) 2 Leerzeichen eingerückt.

Und nein: Die Ausrede "Das mach ich wenn ich fertig bin" lass ich nicht 
gelten.

von Flori (Gast)


Lesenswert?

Hi,
danke für die Antworten.

@Karl heinz Buchegger
Du hast Recht, daran sollte ich arbeiten^^
Ich habe tatsächlich schon mehrere Male vorher versucht die Funktion
aufzuteilen, allerdings sind Versuche wie diese:
1
//...
2
//-------------------------------------------------------------------------
3
// rtcGetMinute
4
//-------------------------------------------------------------------------
5
uint8_t rtcGetMinute()
6
{
7
   return rtcGetRtcData(1);
8
}
9
//-------------------------------------------------------------------------
10
// rtcGetHour
11
//-------------------------------------------------------------------------
12
uint8_t rtcGetHour()
13
{
14
   return rtcGetRtcData(2) & 0x3F;
15
}
16
//...
17
18
19
/////////////////////////////////////////////////////////////////////////////
20
// Main-Funktion
21
/////////////////////////////////////////////////////////////////////////////
22
main()
23
{
24
  DDRB = 0xFF;  // Ausgang
25
  PORTB = 0x00; //
26
      
27
  int alrm = 0; // 0 = kein Alarm  | 1 = Alarm
28
  int ahour= 15;//Alarmstunde
29
  int amin = 10;//Alarmminute
30
  
31
  int menu = 1;//Menü
32
  
33
  int hour = rtcGetHour();
34
  int min  = rtcGetMinute();
35
  
36
37
38
   int i = 0;  
39
  
40
    while (i<1)
41
   {
42
     if (alrm == 1)
43
     {
44
       sbi (PORTB,0);//Licht an  / Ton an
45
    }
46
     
47
     if (menu == 1)
48
     {
49
       lcdGoto(1,1);
50
       lcdWrite(hour);
51
       rtcWaitMs(20);
52
      lcdWrite(":");
53
      lcdWrite(min);
54
       rtcWaitMs(20);
55
       lcdWrite("            ");
56
                        rtcWaitMs(20);
57
     }
58
   
59
     if (ahour == hour && amin == min)
60
    { 
61
      printf("alrm = %d\n", alrm);
62
                 alrm =  1;
63
    }
64
65
     
66
   return 0;
67
   } // Mainloop-Ende
68
}
69
//-------------------------------------------------------------------------
kläglich gescheitert. Irgendwas mache ich da richtig falsch und deshalb 
frage ich um Hilfe bzw einen kleinen Anschub :)
Gruß Flori

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:

> aufzuteilen, allerdings sind Versuche wie diese:
>
>
> main()

Es muss
1
int main()
heissen

> {
>   DDRB = 0xFF;  // Ausgang
>   PORTB = 0x00; //
>
>   int alrm = 0; // 0 = kein Alarm  | 1 = Alarm
>   int ahour= 15;//Alarmstunde
>   int amin = 10;//Alarmminute
>
>   int menu = 1;//Menü
>
>   int hour = rtcGetHour();
>   int min  = rtcGetMinute();

OK. Es gibt also zwei Variablen namens hour und min.
Gut. Die kriegen hier erst mal als Wert die aktuelle Uhrzeit.

...

>     while (i<1)
>    {

dann gehts in die Hauptschleife. Die läuft immer und immer
...

>      if (menu == 1)
>      {
>        lcdGoto(1,1);
>        lcdWrite(hour);

... gut. hour wird ausgegeben ...

>        rtcWaitMs(20);
>       lcdWrite(":");
>       lcdWrite(min);

... und auch min wird ausgegeben ...

>        rtcWaitMs(20);
>        lcdWrite("            ");
>                         rtcWaitMs(20);
>      }
>
>      if (ahour == hour && amin == min)
>     {

... und dann die bewusste Abfrage, die feststellen soll, ob die 
Alarmzeit erreicht ist ...

>       printf("alrm = %d\n", alrm);
>                  alrm =  1;
>     }

... tja.
Und dann ist die Schleife zu Ende.

Nur: Wo, innerhalb dieser Schleife, haben den hour und min eigentlich 
eine Chance jemals an neue Werte zu kommen? Eine Variable, der du nichts 
zuweist, wird auch ihren Wert nicht verändern.
1
int main()
2
{
3
  int alrm = 0; // 0 = kein Alarm  | 1 = Alarm
4
  int ahour= 15;//Alarmstunde
5
  int amin = 10;//Alarmminute
6
  int menu = 1;//Menü
7
  int hour = rtcGetHour();
8
  int min  = rtcGetMinute();
9
10
  DDRB = 0xFF;  // Ausgang
11
  PORTB = 0x00; //
12
 
13
  while (i<1)
14
  {
15
    // aktuelle Uhrzeit vom RTC holen
16
    hour = rtcGetHour();
17
    min  = rtcGetMinute();
18
19
    //
20
    // Soll die Uhrzeit angezeigt werden ?
21
    //
22
    if (menu == 1)
23
    {
24
      lcdGoto(1,1);
25
      lcdWrite(hour);
26
      rtcWaitMs(20);
27
      lcdWrite(":");
28
      lcdWrite(min);
29
      rtcWaitMs(20);
30
      lcdWrite("            ");
31
      rtcWaitMs(20);
32
    }
33
   
34
    //
35
    // Ist die eingestellte Alarmzeit erreicht ?
36
    //
37
    if (ahour == hour && amin == min)
38
    { 
39
      printf("alrm = %d\n", alrm);
40
      alrm =  1;
41
    }
42
43
    //
44
    // läuft noch ein Alarm?
45
    //
46
    if (alrm == 1)
47
    {
48
      sbi (PORTB,0);//Licht an  / Ton an
49
    }
50
  }
51
}

von Flori (Gast)


Lesenswert?

1
//...
2
//-------------------------------------------------------------------------
3
// rtcGetMinute
4
//-------------------------------------------------------------------------
5
uint8_t rtcGetMinute()
6
{
7
   return rtcGetRtcData(1);
8
}
9
//-------------------------------------------------------------------------
10
// rtcGetHour
11
//-------------------------------------------------------------------------
12
uint8_t rtcGetHour()
13
{
14
   return rtcGetRtcData(2) & 0x3F;
15
}
16
//...
17
18
19
/////////////////////////////////////////////////////////////////////////////
20
// Main-Funktion
21
/////////////////////////////////////////////////////////////////////////////
22
int main()
23
{
24
  DDRB = 0xFF;  // Ausgang
25
  PORTB = 0x00; //
26
      
27
  int alrm = 0; // 0 = kein Alarm  | 1 = Alarm
28
  int ahour= 15;//Alarmstunde
29
  int amin = 10;//Alarmminute
30
  
31
  int menu = 1;//Menü
32
  
33
  int hour = rtcGetHour();
34
  int min  = rtcGetMinute();
35
  
36
37
38
   int i = 0;  
39
  
40
    while (i<1)
41
   {
42
     if (alrm == 1)
43
     {
44
       sbi (PORTB,0);//Licht an  / Ton an
45
    }
46
     
47
     if (menu == 1)
48
     {
49
       lcdGoto(1,1);
50
       lcdWrite(hour);
51
       rtcWaitMs(20);
52
       lcdWrite(":");
53
       lcdWrite(min);
54
       rtcWaitMs(20);
55
       lcdWrite("            ");
56
       rtcWaitMs(20);
57
     }
58
   
59
     if (ahour == hour && amin == min)
60
    { 
61
      printf("alrm = %d\n", alrm);
62
                 alrm =  1;
63
    }
64
     
65
66
    printf("hour = %d\n", hour);
67
         hour =  ;
68
    printf("min = %d\n", min);
69
         min =  ;
70
71
     
72
   return 0;
73
   } // Mainloop-Ende
74
}
Um den neuen Wert hatte ich mir bisher gar keine Gedanken gemacht, da 
keine Uhrzeit auf meinem LCD erscheint :(
Deshalb dachte ich, dass die Variable irgendwie falsch deklariert 
wurde...
Warum also wird die Uhrzeit nicht ausgegeben?!
Gruß

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:

> Um den neuen Wert hatte ich mir bisher gar keine Gedanken gemacht, da
> keine Uhrzeit auf meinem LCD erscheint :(
> Deshalb dachte ich, dass die Variable irgendwie falsch deklariert
> wurde...
> Warum also wird die Uhrzeit nicht ausgegeben?!

Weil lcd_write die falsche Funktion dafür ist. Da hat der originale 
Programmierer, bei dem du geklaut hast, nicht wirklich gut nachgedacht, 
welche möglichen Fehler er zulässt, wenn er so einen Haufen lcd_write 
Funktionen macht. Insbesondere die Funktion
1
//---------------------------------------------------------------------------
2
//   lcd_write(..) - sendet ein Zeichen (Daten) an LCD
3
//   PE:   text=Zeichen
4
//---------------------------------------------------------------------------
5
void lcdWrite(char text)
6
{
7
   sbi(PORTD,2);      // RS setzen = Daten
8
   lcdSend(text);      // senden
9
}

ist eine Schnappsidee.

Die Funktion, die du willst heisst
    rtcSendBcdLcd


Edit: Tu dir selbst einen Gefallen und lösche alle lcdWrite Funktionen.
Und danach ergänzt du die LCD Funktionen mit diesen hier:
1
//---------------------------------------------------------------------------
2
//   lcdData(..) - sendet ein Zeichen (Daten) an LCD
3
//   PE:   text=Zeichen
4
//---------------------------------------------------------------------------
5
void lcdData(char text)
6
{
7
   sbi(PORTD,2);      // RS setzen = Daten
8
   lcdSend(text);      // senden
9
}
10
11
//---------------------------------------------------------------------------
12
//   lcdWriteString(..) - sendet eine Zeichenkette an LCD
13
//   Die Zeichenkette muss mit 0x00 abgeschlossen sein
14
//   PE:   pText=Zeiger auf Zeichenkette
15
//---------------------------------------------------------------------------
16
void lcdWriteString(char* pText)
17
{
18
   while(pText[0]!=0)
19
   {
20
      lcdWriteData(pText[0]);
21
      pText++;
22
   }
23
}
24
25
//---------------------------------------------------------------------------
26
//   lcdWriteBytes(..) - sendet eine Bytes an LCD
27
//   PE:   pData=Zeiger auf Daten
28
//      count=Anzahl der zu sendenden Bytes
29
//---------------------------------------------------------------------------
30
void lcdWriteBytes(unsigned char* pData, int count)
31
{
32
   while(count!=0)
33
   {
34
      lcdWriteData(pData[0]);
35
      pData++;
36
      count--;
37
   }
38
}
39
40
//---------------------------------------------------------------------------
41
//   lcdWriteBcd(..) - gibt eine Zahl als Bcd Zahl aus
42
//---------------------------------------------------------------------------
43
void lcdWriteBcd(uint8_t zahl)
44
{
45
   char buff[3]={0};
46
   buff[0] = '0' + (zahl >> 4);
47
   buff[1]   = '0' + (zahl & 0x0F);
48
   lcdWriteString(buff);
49
}

Das wichtigste ist hier: Die Funktion für einen bestimmten Datentypen 
hat einen eindeutigen Namen. Somit überlässt du es nicht dem C++ 
Compiler, für dich die richtige Funktion anhand der tatsächlich 
übergebenen Datentypen zu bestimmen. Soweit bist du noch nicht, dass du 
das in all seinen Feinheiten überblicken könntest.

Für deine Ausgabe benutzt du dann die Funktion lcdWriteBcd

(und die Funktion lcdString entfernst du auch. Ihre Funktion wird durch 
lcdWriteString bereits abgedeckt)

von Flori (Gast)


Lesenswert?

1
/////////////////////////////////////////////////////////////////////////////
2
// Main-Funktion
3
/////////////////////////////////////////////////////////////////////////////
4
int main()
5
{
6
  DDRB = 0xFF;  // Ausgang
7
  PORTB = 0x00; //
8
      
9
  int alrm = 0; // 0 = kein Alarm  | 1 = Alarm
10
  int ahour= 16;
11
  int amin = 9;
12
  
13
  int menu = 1;
14
  
15
  int hour = rtcGetHour();
16
  int min  = rtcGetMinute();
17
  int i = 0;
18
19
20
     
21
  
22
    while (i<1)
23
   {
24
     printf("hour = %d\n", hour);
25
       hour = rtcGetHour();
26
       
27
     printf("min = %d\n", min);
28
       min = rtcGetMinute();
29
       
30
      
31
32
     
33
     if (alrm == 1)
34
     {
35
       sbi (PORTB,0);//Licht an  / Ton an
36
    }
37
     
38
     if (menu == 1)
39
     {
40
       lcdGoto(1,1);
41
       rtcSendBcdLcd(rtcGetHour());
42
       rtcWaitMs(20);
43
      
44
      rtcSendBcdLcd(rtcGetMinute());
45
       rtcWaitMs(20);
46
       
47
     }
48
   
49
     if (ahour == hour && amin == min)
50
    { 
51
      printf("alrm = %d\n", alrm);
52
         alrm =  1;
53
    }
54
55
     
56
   return 0;
57
   } // Mainloop-Ende
58
}
59
//-------------------------------------------------------------------------
Selbst das funktioniert nicht!
Ich glaube ich brauche die Sonderbehandlung ;) Danke für deine Geduld

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:
>
>    return 0;
>    } // Mainloop-Ende
> }


Was hat das return 0 innerhalb der Mainloop zu suchen?
Sagte ich schon, dass du dir viel Ärger mittels konsequenter Einrückerei 
ersparen kannst? Wie kann das sein, dass das 'r' von return und die 
unmittelbar darunter stehende } in der selben Spalte sind? Bei einem { 
wird konsequent um 2 Leerzeichen eingerückt. Bei einem } wird 
konsequent wieder um 2 Leerzeichen rausgerückt. Die letzte } einer 
Funktion, muss wieder in der ersten Spalte sein, sonst stimmt was nicht. 
Zwischen einer { und der schliessenden } kann es keinen Code geben, der 
auf derselben Spalte wie die { } (oder links davon) stehen.

von Flori (Gast)


Lesenswert?

Das "return 0;" ändert nichts an meiner Lage, selbst wenn es weg wäre 
oder verschoben würde....

von Karl H. (kbuchegg)


Lesenswert?

1
     if (menu == 1)
2
     {
3
       lcdGoto(1,1);
4
       rtcSendBcdLcd(rtcGetHour());
5
       rtcWaitMs(20);
6
      
7
      rtcSendBcdLcd(rtcGetMinute());
8
       rtcWaitMs(20);
9
       
10
     }

Warum gibst du hier aus, was dir rtcGetHour bzw. rtcGetMinute liefert? 
Du hast die schon mal abgefragt und die Ergebnisse in hour bzw. min 
gespeichert!

Fang doch erst mal mit kleinen Brötchen an. Dann verhedderst du dich 
auch nicht so leicht
1
int main()
2
{
3
  int hour;
4
  int min;
5
6
  DDRB = 0xFF;  // Ausgang
7
  PORTB = 0x00; //
8
9
  init();
10
      
11
  while( 1 )
12
  {
13
    hour = rtcGetHour();
14
    min = rtcGetMinute();
15
16
    lcdGoto( 1, 1 );
17
    rtcSendBcdLcd( hour );
18
    lcdWrite(":");
19
    rtcSendBcdLcd( min );
20
21
    //
22
    // oder, wenn du wie vorgeschlagen umgebaut hast:
23
    //
24
    // lcdGoto( 1, 1 );
25
    // lcdWriteBcd( hour );
26
    // lcdWriteString( ":" );
27
    // lcdWriteBcd( min );
28
    //
29
  }
30
}


Edit: Hab den Aufruf von init() noch vor der Schleife eingefügt.

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:
> Das "return 0;" ändert nichts an meiner Lage, selbst wenn es weg wäre
> oder verschoben würde....

Doch, das würde es.
Eine Schleife, aus der man mit return aussteigt, wird beendet, selbst 
wenn die Schleife eigentlich für immer laufen sollte :-)

von Karl H. (kbuchegg)


Lesenswert?

Edit: Hab den Aufruf von init() noch vor der Schleife eingefügt.

von Flori (Gast)


Angehängte Dateien:

Lesenswert?

ich entschuldige mich an dieser stelle für meine unordentlichkeit.
das funktioniert immer noch nicht.
Mal eine allgemeine Frage:
Wie ist es möglich, dass
1
void rtcSendBcdLcd(uint8_t zahl)
2
{
3
   char buff[3]={0};
4
   buff[0] = '0' + (zahl >> 4);
5
   buff[1]   = '0' + (zahl & 0x0F);
6
//   lcdWrite(buff);
7
}
lcdWrite vor der Deklaration verwendet wird?

von holgerWie (Gast)


Lesenswert?

Wieso wechselst du deine Dateiendung jetzt
von c nach cpp?

von Flori (Gast)


Angehängte Dateien:

Lesenswert?

sry war grad ein copy paste.

von holger (Gast)


Lesenswert?

>lcdWrite vor der Deklaration verwendet wird?

Weil ganz oben im Code der Prototyp zu lcdWrite() steht.
Die Funktion mit Parametern ist also bekannt.

von Flori (Gast)


Lesenswert?

Und warum funktioniert das Gesamte dann immer noch nicht?

von Flori (Gast)


Lesenswert?

Edit:
@Karl heinz Buchegger
1
//---------------------------------------------------------------------------
2
//   lcdData(..) - sendet ein Zeichen (Daten) an LCD
3
//   PE:   text=Zeichen
4
//---------------------------------------------------------------------------
5
void lcdData(char text)
6
{
7
   sbi(PORTD,2);      // RS setzen = Daten
8
   lcdSend(text);      // senden
9
}
muss das nicht
1
//---------------------------------------------------------------------------
2
//   lcdData(..) - sendet ein Zeichen (Daten) an LCD
3
//   PE:   text=Zeichen
4
//---------------------------------------------------------------------------
5
void lcdWriteData(char text)
6
{
7
   sbi(PORTD,2);      // RS setzen = Daten
8
   lcdSend(text);      // senden
9
}
heißen?

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:
> Und warum funktioniert das Gesamte dann immer noch nicht?

Was funktioniert denn noch nicht?
Kriegst du eine Anzeige?
Welche?
Wenn Anzeige: Ändern sich die Zahlen?

Hast du bedacht, dass in hour bzw. min die entsprechenden Zahlen als BCD 
Zahlen enthalten sind (nach der Art und Weise zu schliessen, wie sie 
ausgegeben werden). D.h. um deine Alarmzeit auf 16 Uhr zu setzen, 
müsstest du 0x16 zuweisen.

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:
> sry war grad ein copy paste.

Hurg. Und ich hab mich schon gewundert, wie du die ganzen lcdWrite 
Funktionen am C-Compiler vorbei gekriegt hast.

Wenn du C++ programmierst, dann lass die Dateiendung bei cpp!
Poste deine Files immer so, wie du sie auch durch den Compiler jagst. 
Nichts verändern, auch nicht die Dateiendung!

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:
> Edit:
> @Karl heinz Buchegger
>
>
1
> //---------------------------------------------------------------------------
2
> //   lcdData(..) - sendet ein Zeichen (Daten) an LCD
3
> //   PE:   text=Zeichen
4
> //---------------------------------------------------------------------------
5
> void lcdData(char text)
6
> {
7
>    sbi(PORTD,2);      // RS setzen = Daten
8
>    lcdSend(text);      // senden
9
> }
10
> 
11
>
> muss das nicht
>
>
1
> //---------------------------------------------------------------------------
2
> //   lcdData(..) - sendet ein Zeichen (Daten) an LCD
3
> //   PE:   text=Zeichen
4
> //---------------------------------------------------------------------------
5
> void lcdWriteData(char text)
6
> {
7
>    sbi(PORTD,2);      // RS setzen = Daten
8
>    lcdSend(text);      // senden
9
> }
10
> 
11
>
> heißen?

Konsequenterweise wär das ein guter Name.
Ich würd sie allerdings

lcdWriteChar

nennen, damit man im Funktionsnamen auch gleich sieht, dass hier ein 
char ausgegeben wird.

von Flori (Gast)


Angehängte Dateien:

Lesenswert?

Also ich habe jetzt zumindest alle Compilerfehler wegbekommen(Prototyp 
zu Lcd...)
Ich bekomme leider überhaupt gar keine Anzeige.Es wird nichts angezeigt.
Nicht einmal das ":"
Im Dateianhang ist nochmal der verbesserte Code. Ich habe mal alle,für 
das Problem, wichitgen Funktionen über die Mainschleife gesetzt.
Gruß

von Karl H. (kbuchegg)


Lesenswert?

Was erhoffst du dir eigentlich von den printf?
Wo soll der printf seine Ausgabe machen?

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:
> Also ich habe jetzt zumindest alle Compilerfehler wegbekommen(Prototyp
> zu Lcd...)
> Ich bekomme leider überhaupt gar keine Anzeige.Es wird nichts angezeigt.
> Nicht einmal das ":"

Dann heist es erst mal abspecken, bis wieder was funktioniert.
1
int main()
2
{
3
  lcdInit();
4
5
  lcdWriteData( 'j' );
6
  lcdWriteString( "juhu" );
7
8
  while( 1 )
9
    ;
10
}

kriegst du eine Ausgabe oder nicht? (Damit testen wir mal, ob deine LCD 
Ausgabe grundsätzlich funktioniert. Ab jetzt wird alles in Frage 
gestellt und einzeln abgetestet, obs auch funktioniert. Und erst im 
Anschluss daran bauen wir das komplette Programm wieder neu auf)

von Flori (Gast)


Lesenswert?

Ja das funktioniert. es kommt "jjuhu_", wie erwartet.

von Karl H. (kbuchegg)


Lesenswert?

Gut, dann der nächste Teil
1
int main()
2
{
3
  uint8_t hour = 0x10;
4
5
  lcdInit();
6
7
  lcdWriteBcd( hour );
8
9
  while( 1 )
10
    ;
11
}

Am LCD muss 10 auftauchen.

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:
> Ja das funktioniert. es kommt "jjuhu_", wie erwartet.

Der _ ist hoffentlich ein Tippfehler. Der darf nicht da sein.

von Flori (Gast)


Lesenswert?

Das war schon immer so bei diesem LCD, mit ein paar Leerzeichen hinten 
dran, verschwindet der Unterstrich.
1
int main()
2
{
3
  int hour = rtcGetHour();
4
5
  lcdInit();
6
  
7
  lcdGoto( 1, 1 );
8
  rtcSendBcdLcd( hour );
9
  
10
  lcdWriteData( 'j' );
11
  lcdWriteString( "juhu" );
12
13
  while( 1 )
14
    ;
15
}
Bei diesem Code ändert sich nichts an der Anzeige. Immer noch "jjuhu".
Also muss der Fehler bei der Deklaration bzw "SendBcdLcd" liegen oder?

von Karl H. (kbuchegg)


Lesenswert?

Dein nächstes Testprogramm (wenn der lcdWriteBcd Test geklappt hat)
1
int main()
2
{
3
  uint8_t min;
4
5
  lcdInit();
6
  lcdWriteString( "Init " );
7
  twiInitMaster( twiAdr );
8
9
  lcdWriteString( "Min " );
10
  min = rtcGetMinute();
11
12
  lcdWriteBcd( min );
13
14
  while( 1 )
15
    ;
16
}

Im Idealfall steht jetzt am LCD
  Init Min 23

(die Zahl kann variieren)

von Flori (Gast)


Lesenswert?

Ja Init Min 25. Wieso 25?

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:

> Bei diesem Code ändert sich nichts an der Anzeige. Immer noch "jjuhu".

Gewöhn dir an, bei Tests die Texte ein wenig zu variieren.
Dadurch kannst du sehen, ob tatsächlich das neue Programm in den µC 
gebrannt wurde, oder du einen Compiler Fehler im Eifer des Gefechts 
übersehen hast.
Du brauchst immer irgendwas in der Form: Erwartete Ausgabe versus 
tatsächliche Ausgabe.

> Also muss der Fehler bei der Deklaration bzw "SendBcdLcd" liegen oder?

Nicht notwendigerweise. Da kann nicht viel schiefgehen.

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:
> Ja Init Min 25. Wieso 25?

Weil es zum Zeitpunkt deines Programmlaufs  19:25 war.

von Karl H. (kbuchegg)


Lesenswert?

Weiter (jetzt kommt der lcdGoto dazu)
1
int main()
2
{
3
  uint8_t min;
4
5
  lcdInit();
6
  twiInitMaster( twiAdr );
7
8
  while( 1 ) {
9
    min = rtcGetMinute();
10
    lcdGoto( 0, 0 );
11
    lcdWriteBcd( min );
12
  }
13
}

von Flori (Gast)


Lesenswert?

1
int main()
2
{
3
  uint8_t min;
4
5
  lcdInit();
6
  twiInitMaster( twiAdr );
7
8
  while( 1 ) {
9
    min = rtcGetMinute();
10
    lcdGoto( 1, 1 );
11
    lcdWriteBcd( min );
12
  }
13
}
Ja das lcdGoto funktioniert

von Karl H. (kbuchegg)


Lesenswert?

Und dann eine volle Uhr (wenn der lcdGoto funktioniert)
(Verfolg auch mit, welche Änderungen ich jeweils mache. Immer kleine, 
testbare Änderungen.
Die Sache mit dem _ lässt mir noch keine Ruhe. Da ist noch was faul)

1
int main()
2
{
3
  uint8_t hour;
4
  uint8_t min;
5
  uint8_t secs;
6
7
  lcdInit();
8
  twiInitMaster( twiAdr );
9
10
  while( 1 ) {
11
    hour = rtcGetHour();
12
    min = rtcGetMinute();
13
    sec = rtcGetSeconds();
14
15
    lcdGoto( 0, 0 );
16
17
    lcdWriteBcd( hour );
18
    lcdWriteChar( ':' );
19
    lcdWriteBcd( min );
20
    lcdWriteChar( ':' );
21
    lcdWriteBcd( sec );
22
  }
23
}

von Flori (Gast)


Lesenswert?

Ja ich verfolge und ich lerne^^
1
int main()
2
{
3
  uint8_t min;
4
  uint8_t hour;
5
6
  lcdInit();
7
  twiInitMaster( twiAdr );
8
9
  while( 1 ) {
10
    min = rtcGetMinute();
11
    hour = rtcGetHour();
12
    lcdGoto( 1, 1 );
13
    lcdWriteBcd( hour );
14
    lcdWriteString( " : " );
15
    lcdWriteBcd( min );
16
  }
17
}
Das funktioniert. Warum funktioniert das jetzt mit dem "uint8"?
Gruß

von Karl H. (kbuchegg)


Lesenswert?

Flori wrote:

> Das funktioniert. Warum funktioniert das jetzt mit dem "uint8"?

Müsste mit einem int genauso funktionieren.
Ein uint8_t ist ein "8-Bit Integer ohne Vorzeichen", hat also in einer 
16 Bit Variable locker Platz.
Aber:
  * Die RTC Funktionen liefern einen uint8_t
  * Die Ausgabefunktion will einen uint8_t haben

Also warum künstlich einen Wert auf 16 Bit aufblasen, wenn er zur 
Ausgabe sowieso wieder auf 8 Bit geschrumpft wird?

von Karl H. (kbuchegg)


Lesenswert?

Weiter.
Mal eine Alarmzeit dazugeben
1
int main()
2
{
3
  uint8_t hour;
4
  uint8_t min;
5
6
  uint8_t alarmHour = 0x19;
7
  uint8_t alarmMin  = 0x58;
8
9
  lcdInit();
10
  twiInitMaster( twiAdr );
11
12
  while( 1 ) {
13
    min = rtcGetMinute();
14
    hour = rtcGetHour();
15
16
    lcdGoto( 1, 1 );
17
18
    lcdWriteBcd( hour );
19
    lcdWriteString( " : " );
20
    lcdWriteBcd( min );
21
22
    if( alarmHour == hour && alarmMin == min ) 
23
      lcdWriteString( " Alarm!" );
24
    else
25
      lcdWriteString( "       " );
26
  }
27
}

Um 19:58 sollte der Alarm losgehen :-)

von Karl H. (kbuchegg)


Lesenswert?

Ich schwanke noch, ob es gescheit ist, die einzelnen Werte als BCD Werte 
zu lassen, oder ob es nicht besser wäre, da "echte" Zahlen daraus zu 
machen. Spätestens wenn es darum geht, die Alarmzeit mit Tastern zu 
vergrößern bzw. zu verringern, wären "echte" Zahlen besser.

von Flori (Gast)


Lesenswert?

Komischer Weise kommt der Unterstrich jetzt nicht mehr^^
Ich bedanke mich recht herzlich bei dir für deine Geduld. Ich möchte 
mich jetzt verbessern und dann helf ich bei euch mit!
Vielen Dank nochmal. Ich habe echt einiges gelernt.

Hier der Code für diejenigen, die ihn vllt nochmal brauchen:
1
int main()
2
{
3
  int alarmh = 0x19;
4
  int alarmm = 0x52;
5
6
7
  uint8_t min;
8
  uint8_t hour;
9
10
  lcdInit();
11
  twiInitMaster( twiAdr );
12
  
13
  
14
15
    while( 1 ) 
16
    {
17
  
18
  if (alarmh == hour && alarmm == min)
19
  { 
20
           lcdGoto( 1, 1 );
21
         lcdWriteString( "Alarm" );
22
  }
23
  else
24
  {  
25
         min = rtcGetMinute();
26
         hour = rtcGetHour();
27
         lcdGoto( 1, 1 );
28
         lcdWriteString( "     " );
29
         lcdWriteBcd( hour );
30
         lcdWriteString( ":" );
31
         lcdWriteBcd( min );
32
        }
33
    
34
    
35
36
    }
37
}

von Flori (Gast)


Lesenswert?

>Ich schwanke noch, ob es gescheit ist, die einzelnen Werte als BCD Werte
>zu lassen, oder ob es nicht besser wäre, da "echte" Zahlen daraus zu
>machen. Spätestens wenn es darum geht, die Alarmzeit mit Tastern zu
>vergrößern bzw. zu verringern, wären "echte" Zahlen besser.

Daran werde ich mich gleich morgen an die Arbeit machen.
Man kann doch die Alarmzeit über die Taster einstellen und speichern(als 
Zahl). Wenn die "Ok Taste" dann gedrückt wird deklariert man zb alarmh 
als 0x X.

von Karl H. (kbuchegg)


Lesenswert?

Der Unterschied ist dir klar?

Bei BCD Zahlen ist jedes Nibble (also 4Bit) als eine Ziffer zu sehen.
Ein Wert von 0x19  repräsentiert also, als BCD Zahl gesehen, die 19. 
Wenn man sich das aber dezimal anzeigen lassen würde, würde da aber 25 
raus kommen.

Der Nachteil bei BCD Zahlen ist, dass man sich bei Arithmetik selbst um 
Überläufe kümmern muss. Nach 0x09 (dezimal 9) kommt nicht 0x0A (dezimal 
10), sondern 0x10 (dezimal 16)

> Wenn die "Ok Taste" dann gedrückt wird deklariert man zb
> alarmh als 0x X.

Nein, das hilft dir nichts. Wenn du die Alarmzeit einstellst, läuft kein 
Compiler mehr. Du musst dich selbst drum kümmern, dass das alles richtig 
gehandhabt wird.

von Flori (Gast)


Lesenswert?

Ja im Notfall eben
1
int alzw = 10; //Ok Taste --> Zwischenwert AlarmStunde
2
int alarmh = 0;//verwendete Var
3
4
5
 if (alzw == 10)
6
  { alarmh = 0x10); }
7
8
 if (alzw == 9)
9
  { alarmh = 0x09); }
Wobei das bei den Minuten ziemlich stressig wäre

von Stefan W. (wswbln)


Lesenswert?

Karl heinz Buchegger wrote:
> Die Sache mit dem _ lässt mir noch keine Ruhe. Da ist noch was faul)

LOL!    --> Cursor?

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.