mikrocontroller.net

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


Autor: Flori (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Teplotaxl X. (t3plot4x1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if (Alarmstunde == AktuelleStunde)
{
if (Alarmminute == AktuelleMinute)
{ //Alarm}
}
lässt sich vereinfachen
if (Alarmstunde == AktuelleStunde && Alarmminute == AktuelleMinute)
{ //Alarm}
}
PS: Code als *.c anhängen, dann geht auch die Syntaxhervorhebung

Autor: Flori (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ok hier nochmal der Code in C.

Autor: Emperor_L0ser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: karlheinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was meinst du?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 ...
void rtcSendTimeLcd()
{
   lcdGoto(1,1);
   rtcSendBcdLcd(rtcGetHour());
   rtcWaitMs(20);
   lcdWrite(":");
   rtcSendBcdLcd(rtcGetMinute());
   rtcWaitMs(20);
   lcdWrite(":");
}

... 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.

...
main()
{
      DDRB = 0xFF;  // Ausgang
      PORTB = 0x00; //
      
  int alrm = 0; // 0 = kein Alarm  | 1 = Alarm

   init();   //
   while (true)    // Mainloop-Begin
   {
   if (alarm == 1)
   {
   sbi (PORTB,0);//Licht an  / Ton an
  }
   else
   {
   rtcSendTimeLcd();
   }
   
   } // Mainloop-Ende
}

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

Das hier
main()
{
  DDRB = 0xFF;  // Ausgang
  PORTB = 0x00; //
      
  int alrm = 0; // 0 = kein Alarm  | 1 = Alarm

  init();   //
  while (true)    // Mainloop-Begin
  {
    if (alarm == 1)
    {
      sbi (PORTB,0);//Licht an  / Ton an
    }
    else
    {
      rtcSendTimeLcd();
    }
   
  } // Mainloop-Ende
}

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.

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:

//...
//-------------------------------------------------------------------------
// rtcGetMinute
//-------------------------------------------------------------------------
uint8_t rtcGetMinute()
{
   return rtcGetRtcData(1);
}
//-------------------------------------------------------------------------
// rtcGetHour
//-------------------------------------------------------------------------
uint8_t rtcGetHour()
{
   return rtcGetRtcData(2) & 0x3F;
}
//...


/////////////////////////////////////////////////////////////////////////////
// Main-Funktion
/////////////////////////////////////////////////////////////////////////////
main()
{
  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();
  


   int i = 0;  
  
    while (i<1)
   {
     if (alrm == 1)
     {
       sbi (PORTB,0);//Licht an  / Ton an
    }
     
     if (menu == 1)
     {
       lcdGoto(1,1);
       lcdWrite(hour);
       rtcWaitMs(20);
      lcdWrite(":");
      lcdWrite(min);
       rtcWaitMs(20);
       lcdWrite("            ");
                        rtcWaitMs(20);
     }
   
     if (ahour == hour && amin == min)
    { 
      printf("alrm = %d\n", alrm);
                 alrm =  1;
    }

     
   return 0;
   } // Mainloop-Ende
}
//-------------------------------------------------------------------------
kläglich gescheitert. Irgendwas mache ich da richtig falsch und deshalb 
frage ich um Hilfe bzw einen kleinen Anschub :)
Gruß Flori

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flori wrote:

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

Es muss
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.
int main()
{
  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();

  DDRB = 0xFF;  // Ausgang
  PORTB = 0x00; //
 
  while (i<1)
  {
    // aktuelle Uhrzeit vom RTC holen
    hour = rtcGetHour();
    min  = rtcGetMinute();

    //
    // Soll die Uhrzeit angezeigt werden ?
    //
    if (menu == 1)
    {
      lcdGoto(1,1);
      lcdWrite(hour);
      rtcWaitMs(20);
      lcdWrite(":");
      lcdWrite(min);
      rtcWaitMs(20);
      lcdWrite("            ");
      rtcWaitMs(20);
    }
   
    //
    // Ist die eingestellte Alarmzeit erreicht ?
    //
    if (ahour == hour && amin == min)
    { 
      printf("alrm = %d\n", alrm);
      alrm =  1;
    }

    //
    // läuft noch ein Alarm?
    //
    if (alrm == 1)
    {
      sbi (PORTB,0);//Licht an  / Ton an
    }
  }
}

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
//...
//-------------------------------------------------------------------------
// rtcGetMinute
//-------------------------------------------------------------------------
uint8_t rtcGetMinute()
{
   return rtcGetRtcData(1);
}
//-------------------------------------------------------------------------
// rtcGetHour
//-------------------------------------------------------------------------
uint8_t rtcGetHour()
{
   return rtcGetRtcData(2) & 0x3F;
}
//...


/////////////////////////////////////////////////////////////////////////////
// Main-Funktion
/////////////////////////////////////////////////////////////////////////////
int main()
{
  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();
  


   int i = 0;  
  
    while (i<1)
   {
     if (alrm == 1)
     {
       sbi (PORTB,0);//Licht an  / Ton an
    }
     
     if (menu == 1)
     {
       lcdGoto(1,1);
       lcdWrite(hour);
       rtcWaitMs(20);
       lcdWrite(":");
       lcdWrite(min);
       rtcWaitMs(20);
       lcdWrite("            ");
       rtcWaitMs(20);
     }
   
     if (ahour == hour && amin == min)
    { 
      printf("alrm = %d\n", alrm);
                 alrm =  1;
    }
     

    printf("hour = %d\n", hour);
         hour =  ;
    printf("min = %d\n", min);
         min =  ;

     
   return 0;
   } // Mainloop-Ende
}
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ß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
//---------------------------------------------------------------------------
//   lcd_write(..) - sendet ein Zeichen (Daten) an LCD
//   PE:   text=Zeichen
//---------------------------------------------------------------------------
void lcdWrite(char text)
{
   sbi(PORTD,2);      // RS setzen = Daten
   lcdSend(text);      // senden
}

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:
//---------------------------------------------------------------------------
//   lcdData(..) - sendet ein Zeichen (Daten) an LCD
//   PE:   text=Zeichen
//---------------------------------------------------------------------------
void lcdData(char text)
{
   sbi(PORTD,2);      // RS setzen = Daten
   lcdSend(text);      // senden
}

//---------------------------------------------------------------------------
//   lcdWriteString(..) - sendet eine Zeichenkette an LCD
//   Die Zeichenkette muss mit 0x00 abgeschlossen sein
//   PE:   pText=Zeiger auf Zeichenkette
//---------------------------------------------------------------------------
void lcdWriteString(char* pText)
{
   while(pText[0]!=0)
   {
      lcdWriteData(pText[0]);
      pText++;
   }
}

//---------------------------------------------------------------------------
//   lcdWriteBytes(..) - sendet eine Bytes an LCD
//   PE:   pData=Zeiger auf Daten
//      count=Anzahl der zu sendenden Bytes
//---------------------------------------------------------------------------
void lcdWriteBytes(unsigned char* pData, int count)
{
   while(count!=0)
   {
      lcdWriteData(pData[0]);
      pData++;
      count--;
   }
}

//---------------------------------------------------------------------------
//   lcdWriteBcd(..) - gibt eine Zahl als Bcd Zahl aus
//---------------------------------------------------------------------------
void lcdWriteBcd(uint8_t zahl)
{
   char buff[3]={0};
   buff[0] = '0' + (zahl >> 4);
   buff[1]   = '0' + (zahl & 0x0F);
   lcdWriteString(buff);
}

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)

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
/////////////////////////////////////////////////////////////////////////////
// Main-Funktion
/////////////////////////////////////////////////////////////////////////////
int main()
{
  DDRB = 0xFF;  // Ausgang
  PORTB = 0x00; //
      
  int alrm = 0; // 0 = kein Alarm  | 1 = Alarm
  int ahour= 16;
  int amin = 9;
  
  int menu = 1;
  
  int hour = rtcGetHour();
  int min  = rtcGetMinute();
  int i = 0;


     
  
    while (i<1)
   {
     printf("hour = %d\n", hour);
       hour = rtcGetHour();
       
     printf("min = %d\n", min);
       min = rtcGetMinute();
       
      

     
     if (alrm == 1)
     {
       sbi (PORTB,0);//Licht an  / Ton an
    }
     
     if (menu == 1)
     {
       lcdGoto(1,1);
       rtcSendBcdLcd(rtcGetHour());
       rtcWaitMs(20);
      
      rtcSendBcdLcd(rtcGetMinute());
       rtcWaitMs(20);
       
     }
   
     if (ahour == hour && amin == min)
    { 
      printf("alrm = %d\n", alrm);
         alrm =  1;
    }

     
   return 0;
   } // Mainloop-Ende
}
//-------------------------------------------------------------------------
Selbst das funktioniert nicht!
Ich glaube ich brauche die Sonderbehandlung ;) Danke für deine Geduld

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Flori (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
     if (menu == 1)
     {
       lcdGoto(1,1);
       rtcSendBcdLcd(rtcGetHour());
       rtcWaitMs(20);
      
      rtcSendBcdLcd(rtcGetMinute());
       rtcWaitMs(20);
       
     }

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
int main()
{
  int hour;
  int min;

  DDRB = 0xFF;  // Ausgang
  PORTB = 0x00; //

  init();
      
  while( 1 )
  {
    hour = rtcGetHour();
    min = rtcGetMinute();

    lcdGoto( 1, 1 );
    rtcSendBcdLcd( hour );
    lcdWrite(":");
    rtcSendBcdLcd( min );

    //
    // oder, wenn du wie vorgeschlagen umgebaut hast:
    //
    // lcdGoto( 1, 1 );
    // lcdWriteBcd( hour );
    // lcdWriteString( ":" );
    // lcdWriteBcd( min );
    //
  }
}


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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Flori (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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
void rtcSendBcdLcd(uint8_t zahl)
{
   char buff[3]={0};
   buff[0] = '0' + (zahl >> 4);
   buff[1]   = '0' + (zahl & 0x0F);
//   lcdWrite(buff);
}
lcdWrite vor der Deklaration verwendet wird?

Autor: holgerWie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso wechselst du deine Dateiendung jetzt
von c nach cpp?

Autor: Flori (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
sry war grad ein copy paste.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>lcdWrite vor der Deklaration verwendet wird?

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

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und warum funktioniert das Gesamte dann immer noch nicht?

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Edit:
@Karl heinz Buchegger
//---------------------------------------------------------------------------
//   lcdData(..) - sendet ein Zeichen (Daten) an LCD
//   PE:   text=Zeichen
//---------------------------------------------------------------------------
void lcdData(char text)
{
   sbi(PORTD,2);      // RS setzen = Daten
   lcdSend(text);      // senden
}

muss das nicht
//---------------------------------------------------------------------------
//   lcdData(..) - sendet ein Zeichen (Daten) an LCD
//   PE:   text=Zeichen
//---------------------------------------------------------------------------
void lcdWriteData(char text)
{
   sbi(PORTD,2);      // RS setzen = Daten
   lcdSend(text);      // senden
}

heißen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flori wrote:
> Edit:
> @Karl heinz Buchegger
>
>
> //---------------------------------------------------------------------------
> //   lcdData(..) - sendet ein Zeichen (Daten) an LCD
> //   PE:   text=Zeichen
> //---------------------------------------------------------------------------
> void lcdData(char text)
> {
>    sbi(PORTD,2);      // RS setzen = Daten
>    lcdSend(text);      // senden
> }
> 
> 
> muss das nicht
>
>
> //---------------------------------------------------------------------------
> //   lcdData(..) - sendet ein Zeichen (Daten) an LCD
> //   PE:   text=Zeichen
> //---------------------------------------------------------------------------
> void lcdWriteData(char text)
> {
>    sbi(PORTD,2);      // RS setzen = Daten
>    lcdSend(text);      // senden
> }
> 
> 
> 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.

Autor: Flori (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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ß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was erhoffst du dir eigentlich von den printf?
Wo soll der printf seine Ausgabe machen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
int main()
{
  lcdInit();

  lcdWriteData( 'j' );
  lcdWriteString( "juhu" );

  while( 1 )
    ;
}

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)

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja das funktioniert. es kommt "jjuhu_", wie erwartet.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut, dann der nächste Teil
int main()
{
  uint8_t hour = 0x10;

  lcdInit();

  lcdWriteBcd( hour );

  while( 1 )
    ;
}

Am LCD muss 10 auftauchen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flori wrote:
> Ja das funktioniert. es kommt "jjuhu_", wie erwartet.

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

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das war schon immer so bei diesem LCD, mit ein paar Leerzeichen hinten 
dran, verschwindet der Unterstrich.
int main()
{
  int hour = rtcGetHour();

  lcdInit();
  
  lcdGoto( 1, 1 );
  rtcSendBcdLcd( hour );
  
  lcdWriteData( 'j' );
  lcdWriteString( "juhu" );

  while( 1 )
    ;
}
Bei diesem Code ändert sich nichts an der Anzeige. Immer noch "jjuhu".
Also muss der Fehler bei der Deklaration bzw "SendBcdLcd" liegen oder?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein nächstes Testprogramm (wenn der lcdWriteBcd Test geklappt hat)
int main()
{
  uint8_t min;

  lcdInit();
  lcdWriteString( "Init " );
  twiInitMaster( twiAdr );

  lcdWriteString( "Min " );
  min = rtcGetMinute();

  lcdWriteBcd( min );

  while( 1 )
    ;
}

Im Idealfall steht jetzt am LCD
  Init Min 23

(die Zahl kann variieren)

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja Init Min 25. Wieso 25?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flori wrote:
> Ja Init Min 25. Wieso 25?

Weil es zum Zeitpunkt deines Programmlaufs  19:25 war.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiter (jetzt kommt der lcdGoto dazu)
int main()
{
  uint8_t min;

  lcdInit();
  twiInitMaster( twiAdr );

  while( 1 ) {
    min = rtcGetMinute();
    lcdGoto( 0, 0 );
    lcdWriteBcd( min );
  }
}

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int main()
{
  uint8_t min;

  lcdInit();
  twiInitMaster( twiAdr );

  while( 1 ) {
    min = rtcGetMinute();
    lcdGoto( 1, 1 );
    lcdWriteBcd( min );
  }
}
Ja das lcdGoto funktioniert

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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)

int main()
{
  uint8_t hour;
  uint8_t min;
  uint8_t secs;

  lcdInit();
  twiInitMaster( twiAdr );

  while( 1 ) {
    hour = rtcGetHour();
    min = rtcGetMinute();
    sec = rtcGetSeconds();

    lcdGoto( 0, 0 );

    lcdWriteBcd( hour );
    lcdWriteChar( ':' );
    lcdWriteBcd( min );
    lcdWriteChar( ':' );
    lcdWriteBcd( sec );
  }
}

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ich verfolge und ich lerne^^
int main()
{
  uint8_t min;
  uint8_t hour;

  lcdInit();
  twiInitMaster( twiAdr );

  while( 1 ) {
    min = rtcGetMinute();
    hour = rtcGetHour();
    lcdGoto( 1, 1 );
    lcdWriteBcd( hour );
    lcdWriteString( " : " );
    lcdWriteBcd( min );
  }
}
Das funktioniert. Warum funktioniert das jetzt mit dem "uint8"?
Gruß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiter.
Mal eine Alarmzeit dazugeben
int main()
{
  uint8_t hour;
  uint8_t min;

  uint8_t alarmHour = 0x19;
  uint8_t alarmMin  = 0x58;

  lcdInit();
  twiInitMaster( twiAdr );

  while( 1 ) {
    min = rtcGetMinute();
    hour = rtcGetHour();

    lcdGoto( 1, 1 );

    lcdWriteBcd( hour );
    lcdWriteString( " : " );
    lcdWriteBcd( min );

    if( alarmHour == hour && alarmMin == min ) 
      lcdWriteString( " Alarm!" );
    else
      lcdWriteString( "       " );
  }
}

Um 19:58 sollte der Alarm losgehen :-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
int main()
{
  int alarmh = 0x19;
  int alarmm = 0x52;


  uint8_t min;
  uint8_t hour;

  lcdInit();
  twiInitMaster( twiAdr );
  
  

    while( 1 ) 
    {
  
  if (alarmh == hour && alarmm == min)
  { 
           lcdGoto( 1, 1 );
         lcdWriteString( "Alarm" );
  }
  else
  {  
         min = rtcGetMinute();
         hour = rtcGetHour();
         lcdGoto( 1, 1 );
         lcdWriteString( "     " );
         lcdWriteBcd( hour );
         lcdWriteString( ":" );
         lcdWriteBcd( min );
        }
    
    

    }
}

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Flori (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja im Notfall eben
int alzw = 10; //Ok Taste --> Zwischenwert AlarmStunde
int alarmh = 0;//verwendete Var


 if (alzw == 10)
  { alarmh = 0x10); }

 if (alzw == 9)
  { alarmh = 0x09); }
Wobei das bei den Minuten ziemlich stressig wäre

Autor: Stefan Wimmer (wswbln)
Datum:

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

LOL!    --> Cursor?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.