mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik I2C Real Time Clock/Calendar (DS1337


Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe hier einen ISL12057 im Betrieb.

• Pin Compatible to Maxim DS1337
• Functionally Equivalent to Maxim DS1337

Dabei setze ich erfolgreich eine Zeit mittels:
// DS1307 RTC ROUTINES
#define DS1307 0xD0 // I2C bus address of DS1307 RTC
#define SECONDS_REGISTER 0x00
#define MINUTES_REGISTER 0x01
#define HOURS_REGISTER 0x02
#define DAYOFWK_REGISTER 0x03
#define DAYS_REGISTER 0x04
#define MONTHS_REGISTER 0x05
#define YEARS_REGISTER 0x06
#define CONTROL_REGISTER 0x07
#define RAM_BEGIN 0x08
#define RAM_END 0x3F

void SetTimeDate()
// simple, hard-coded way to set the date.
{
  I2C_WriteRegister(DS1307, MONTHS_REGISTER, 0x08);
  I2C_WriteRegister(DS1307, DAYS_REGISTER, 0x31);
  I2C_WriteRegister(DS1307, YEARS_REGISTER, 0x17);
  I2C_WriteRegister(DS1307, HOURS_REGISTER, 0x08 + 0x40); // add 0x40 for PM
  I2C_WriteRegister(DS1307, MINUTES_REGISTER, 0x51);
  I2C_WriteRegister(DS1307, SECONDS_REGISTER, 0x00);
}
und lese diese wieder mit:
void DS1307_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds)
// returns hours, minutes, and seconds in BCD format
{
  *hours = I2C_ReadRegister(DS1307, HOURS_REGISTER);
  *minutes = I2C_ReadRegister(DS1307, MINUTES_REGISTER);
  *seconds = I2C_ReadRegister(DS1307, SECONDS_REGISTER);
  if (*hours & 0x40) // 12hr mode:
    *hours &= 0x1F; // use bottom 5 bits (pm bit = temp & 0x20)
  else
    *hours &= 0x3F; // 24hr mode: use bottom 6 bits
}

Doch wenn ich mir die Sekunden in einer Endlosschleife auf dem Display 
ausgeben lasse (natürlich frage ich genauso oft den Chip ab), dann 
erhalte ich keine "neue" Uhrzeit. Also der Sekundenzeiger bleibt still.

Die Hardware ist in 20-Facher Ausführung vorhanden und ging auch bereits 
mit einem anderem Chip (closed Source) an den Kunden ohne Reklamation.
Daher gehe ich davon aus, dass dort kein Fehler ist.

Muss ich dem DS1337 noch irgendwie sagen, dass er loslaufen darf/soll?
Ich finde keinerlei Hinweise diesbezüglich im Datenblatt.

Ich danke euch schon mal für eure Mühen. gute Nacht ;)

Oekel

: Verschoben durch Moderator
Autor: Johnny B. (johnnyb)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Das ist jetzt keine Antwort auf Deine Frage, aber solltest Du nicht die 
Stunden-, Minuten- und Sekundenregister mit einem einzigen Lesebefehl 
"gleichzeitig" lesen?
Ansonsten kann es zu inkonsistenten Daten kommen; d.h. das z.B. die 
Stunden und Minuten noch zu einer alten Zeit gehören und die Sekunden 
schon zu einer neuen.

Bei Deiner Anwendung ist es vielleicht nicht so kritisch, da es nur jede 
Minute mal vorkommen kann, aber bei schnelleren Angelegenheiten ist 
sowas gar nicht gut.

Autor: Aa B. (aaab)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D a v i d K. schrieb:
> Hi,
>
> ich habe hier einen ISL12057 im Betrieb.
>

>
> Doch wenn ich mir die Sekunden in einer Endlosschleife auf dem Display
> ausgeben lasse (natürlich frage ich genauso oft den Chip ab), dann


Ich hoffe dass du die I2C bus alles richtig initialisiert hast, nehme 
mal an, Ja.

> erhalte ich keine "neue" Uhrzeit. Also der Sekundenzeiger bleibt still.
Hast Du
*seconds
 in Debugger beobachtet, bleibt der Wert still wenn
DS1307_GetTime(&HH,&MM,&SS)
 in main() aufgerufen wird?

: Bearbeitet durch User
Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D a v i d K. schrieb:
> Muss ich dem DS1337 noch irgendwie sagen, dass er loslaufen darf/soll?
> Ich finde keinerlei Hinweise diesbezüglich im Datenblatt.

dem 1307 muss man das jedenfalls sagen beim 1337 habe ich auch nichts 
gefunden

aber das die DS13xx so ungenau sind arbeite ich eh nur noch mit DS3231
void DS1307new::stopClock(void)         // set the ClockHalt bit high to stop the rtc
{ Wire.beginTransmission(DS1307_ID);
  printIIC(0x00);                      // Register 0x00 holds the oscillator start/stop bit
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ID, 1);
  second = readIIC() | 0x80;       // save actual seconds and OR sec with bit 7 (sart/stop bit) = clock stopped
  Wire.beginTransmission(DS1307_ID);
  printIIC(0x00);
  printIIC(second);                    // write seconds back and stop the clock
  Wire.endTransmission();
}

void DS1307new::startClock(void)        // set the ClockHalt bit low to start the rtc
{ Wire.beginTransmission(DS1307_ID);
  printIIC(0x00);                      // Register 0x00 holds the oscillator start/stop bit
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ID, 1);
  second = readIIC() & 0x7f;       // save actual seconds and AND sec with bit 7 (sart/stop bit) = clock started
  Wire.beginTransmission(DS1307_ID);
  printIIC(0x00);
  printIIC(second);                    // write seconds back and start the clock
  Wire.endTransmission();
}

: Bearbeitet durch User
Autor: Hurra (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lies mal "Control Register (0Eh)"

ist EOSC LOW?
Sollte zwar mit LOW initialisiet sein, aber nachprüfen schadet nicht.

Was ist mit "Status Register (0Fh)"
Was sagt OSF? Das muss LOW sein.

Haste einen Quarz dran, schwingt der?

Wenn du einen 1Hz auf den Ausgang schaltest, tut sich was?

Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hurra schrieb:

> ist EOSC LOW?
> Sollte zwar mit LOW initialisiet sein, aber nachprüfen schadet nicht.


Gerade noch mal kontrolliert: JA

Er läuft wohl doch, allerdings viel zu langsam: Das Increment ist so 
alle 40Sekunden.

Also mit MINUTENREGISTER habe ich es definitiv nicht verwechselt, passt 
also auch nicht.
Der Quarz passt auch, es sein denn ihr erzählt mir jetzt, dass man den 
Takt durch zu heißes Löten völlig verändern kann?

Grüße Oekel

Autor: Bastian W. (jackfrost)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du die Frequenz mal am SQW Pin mal gemessen ?

Gruß JackFrost

Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bastian W. schrieb:
> Hast du die Frequenz mal am SQW Pin mal gemessen ?
>
> Gruß JackFrost

Scheinbar ist wirklich der Chip oder der Quarz im A****
Andere Platinen zeigen bei gleichem Code das gewünschte Ergebnis.

Habe dennoch etwas aus den Antworten gelernt, daher vielen Dank und 
Entschuldigung für die Umstände.

Grüße Oekel

Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt muss ich doch noch mal stören.
Wieso funktionieren folgende funktion bei Skunden wunderbar, erzeugen 
mir jedoch falsche Berechnungen bei minuten und stunden?
static inline int bcd_decimal(uint8_t hex) {
  int dec = ((hex & 0xF0) >> 4) * 10 + (hex & 0x0F);
  return dec;
}
static inline int decimal_bcd(uint8_t dec) {
  int hex = ((dec / 10) << 4) | (dec % 10);
  return hex;
}

Angewendet:
I2C_WriteRegister(DS1307, MINUTES_REGISTER, decimal_bcd(58));
...
...
void lcd_printInt(uint16_t value, uint8_t c, bool leadingZeros)
{
  char str[c];
  utoa(value, str, 10);
  if(leadingZeros)
  {

    for( uint8_t i = getDigitCount(value); i < c; i++)
      lcd_print_P(PSTR("0"));
  }
  lcd_print(str);
}
...
lcd_printInt(bcd_decimal(minutes), 2, true);


Grüße Oekel

Autor: Bastian W. (jackfrost)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du die RTC auf 24h gestellt?

Welche Werte hast du für Minuten und Stunden ( BCD als auch dezimal )

Gruß JackFrost

Autor: Hurra (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D a v i d K. schrieb:
> Jetzt muss ich doch noch mal stören.
> Wieso funktionieren folgende funktion bei Skunden wunderbar, erzeugen
> mir jedoch falsche Berechnungen bei minuten und stunden?
>
>
> static inline int bcd_decimal(uint8_t hex) {
>   int dec = ((hex & 0xF0) >> 4) * 10 + (hex & 0x0F);
>   return dec;
> }
> static inline int decimal_bcd(uint8_t dec) {
>   int hex = ((dec / 10) << 4) | (dec % 10);
>   return hex;
> }
> 

Das will mir auf den ersten Blick richtig erscheinen.

Eine mögliche Erklärung für das Problem der Stunden findest du im 
Datenblatt auf S8 (Abschnitt Timekeeper Register).

Zumindest bei den Stunden befinden sich im Zeitregister auch Statusbits 
(10/24, AM/PM), die musst man ausmarkieren.
Bei den Minuten kommt mir das komisch vor, da müsste es eine andere 
Erklärung geben. Möglicherweise kann man aber das Bit 7 manuell setzen.

Schau dir die Werte in Hex an, die in die Funkion reingehen, und was sie 
zurückliefert. Dann überleg dir auf Papier, wie das zustandekokmmt.

Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hurra schrieb:

> Das will mir auf den ersten Blick richtig erscheinen.
>
Ich denke auch, dass die Funktionen richtig sind, denn wenn ich mal hin 
UND her konvertiere und es auf dem Display ausgebe, so bekomme ich die 
Zahlen von 00-59 korrekt dargestellt.

Dann habe ich nun noch mal folgendes probiert:
for(uint8_t i= 0; i< 60; i++){
    lcd_gotolc(1, 1);
    I2C_WriteRegister(DS1307, MINUTES_REGISTER, decimal_bcd(i));
    DS1307_GetTime(&hours, &minutes, &seconds);
    lcd_printBinary(minutes);
    lcd_gotolc(2, 1);
    lcd_printInt(bcd_decimal(minutes), 2, true);
    wait_10ms(50);
  }

zuerst natürlich mit sekunden und hatte eine "ständig ändernde" (also 
korrekte) Anzeige.
Das Gleiche 1:1 wie oben abgebildet bleibt zu 90% auf 0b00010100 (10) 
stehen und wechselt 1x auf 0b0010000 hin und zurück.

Ich habe die bitte Vermutung, dass auch dieser Chip defekt ist und ich 
eine ganze Reihe Montagsmodelle bekommen habe.

Kann so etwas sein? Also einzelne Register im A* ? Und wie geht man da 
vor? Ich habe mir 500 Stück davon hingelegt.

Grüße Oekel

Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe jetzt noch mal 10 weitere Chips ausprobiert und überall das gleiche 
Ergebnis.

Nehmen wir mal folgendes:
  for(uint8_t i= 0; i<= 13; i++){
    lcd_gotolc(1, 1);
    I2C_WriteRegister(DS1307, SECONDS_REGISTER, decimal_bcd(i));
    I2C_WriteRegister(DS1307, MINUTES_REGISTER, decimal_bcd(i));
    DS1307_GetTime(&hours, &minutes, &seconds);
    uint8_t sec = bcd_decimal(seconds);
    uint8_t min = bcd_decimal(minutes);
    lcd_printBinary(sec);
    //lcd_printInt(sec, 2, true);
    lcd_gotolc(2, 1);
    lcd_printBinary(min);
    //lcd_printInt(min, 2, true);
    wait_10ms(50);
  }
so scheinen beide Register sinnige Werte zu liefern. (Also ich erhalte 
eine binäre Ausgabe für ALLE gewünschten Werte.
Doch kommentiere ich die beiden Zeilen wieder ein, so komme ich bei 
"sec" ans Ziel mit 13 und bei "min" nur bis 10 und erhalte für die 
theorischen 11,12,13 nur 00.

Erhöhe ich die "Stellenanzahl" (=c) für meine Funktion:
void lcd_printInt(uint16_t value, uint8_t c, bool leadingZeros)
{
  char str[c];
  utoa(value, str, 10);
  if(leadingZeros)
  {

    for( uint8_t i = getDigitCount(value); i < c; i++)
      lcd_print_P(PSTR("0"));
  }
  lcd_print(str);
}
 auf 3, so bekomme ich auch die richtigen Werte von 0-59 angezeigt.

Aber wieso ist das so? Wieso klappt die Umwandlung bei Sekunden mit char 
str[2]; und bei Minuten nur mit char str[3];

Zuvor habe ich ja die eingängigen Binärwerte miteinander verglichen und 
auch gleiche Werte erhalten.
Hier noch mal die komplette Funktion dazu:
void lcd_printBinary(uint8_t bin){
  for(uint8_t i= 0; i< 8; i++){
    if(bin & (0b10000000 >> i )){
      lcd_print_P(PSTR("1"));
    }else{
      lcd_print_P(PSTR("0"));
    }
  }
}

Hat Jemand für mich hier noch eine Bahnbrechende Idee, wo ich mich da 
vertue?

Grüße Oekel

: Bearbeitet durch User
Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D a v i d K. schrieb:
> Habe jetzt noch mal 10 weitere Chips ausprobiert und überall das gleiche
> Ergebnis.

und warum nicht DS3231?
war für mich stressfreier.

Autor: Bastian W. (jackfrost)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Normal muss doch der String mit \0 terminiert werden. Ggf. überschreibt 
es dir etwas im Speicher bei Minuten und Stunden mit dem \0.

Kannst du den µC debuggen und dir den Speicher vor und nach dem 
beschreiben der Sekunden und Minuten ansehen ?

Gruß JackFrost

Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bastian W. schrieb:

> Kannst du den µC debuggen und dir den Speicher vor und nach dem
> beschreiben der Sekunden und Minuten ansehen ?

Nein, leider keine Debugger-Fähigkeiten (in der Hardware)
Es scheint aber ein ganz anderes Verständnisproblem zu existieren.

Habe jetzt mal 23:58:48 eingestellt und nach 12 Sekunden zeigt er mir 
für eine Minute lang 23:59:00_ an. Ab 00:00:00 zählt er brav Sekunden 
und Minuten hoch.
Lass ihn gerade mal laufen....

Also bis 00:10:00 läuft er durch, danach bewegen sich die Sekunden schon 
wieder nicht. auch bei Minute 11,12,13,14,15...
Gleiche Ergebnis, wenn ich initial einen dieser Werte einstelle.
Also zwischen 00:00:00 - 00:09:59 sehe ich Sekunden, danach nur noch 
Minuten und Stunden. (zB. auch 13:09:00)

: Bearbeitet durch User
Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt lief das Teil ca 1 Std. und die Sekunden-Werte stehen ebenfalls 
bei 01:01:00, 01:02:00, 01:03:00, ...

Da ist doch irgendwie der Wurm drin. :'(

Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, es muss etwas mit dem BCD Format zu tun haben.
Also der Chip funktioniert korrekt, da bin ich mir mittlerweile 100% 
sicher.

Trotzdem zerschieße ich mir irgendwie die Variablen.
Was mich zu dieser Überzeugung bringt, möchte ich mit einigen 
Variationen meines Testcodes darstellen. In der Hoffnung, dass mich 
Jemand von euch erleuchten kann.
(Danke an dieser Stelle für die Geduld und das Lesen)

Als Testausgabe habe ich zwei Displays (7-segment & LCD)
Folgenden Code:
void test_Clock() {

  cli();
  uint8_t hours, minutes, seconds, months, days, years;
  DS1307_GetTime(&hours, &minutes, &seconds);
  //DS1307_GetDate(&years, &months, &days);

  print_timeAtLine(1, bcd_decimal(hours), bcd_decimal(minutes), bcd_decimal(seconds));


  SS_SetDigits(minutes >> 4, // 10 hour digit
    minutes & 0x0F, // 1 hour digit
    seconds >> 4, // 10 minute digit
    seconds & 0x0F, // 1 minute digit
    1); // turn on colon
  sei();
}

void print_timeAtLine(uint8_t line, uint8_t hours, uint8_t minutes, uint8_t seconds) {
  //____hh:mm:ss____
  lcd_gotolc(line, 5);
  lcd_printInt(hours, 2, true);
  lcd_print_P(PSTR(":"));
  lcd_printInt(minutes, 2, true);
  lcd_print_P(PSTR(":"));
  lcd_printInt(seconds, 2, true);

}

Ergibt eine korrekte sekündliche Anzeige auf dem 7-Segment, jedoch 
bleiben die Sekunden auf dem LCD bis auf die bereits erwähnten Minunte 
1-9 auf "00".
void test_Clock() {

  cli();
  uint8_t hours, minutes, seconds, months, days, years;
  DS1307_GetTime(&hours, &minutes, &seconds);
  //DS1307_GetDate(&years, &months, &days);

  print_timeAtLine(1, bcd_decimal(hours), bcd_decimal(minutes), bcd_decimal(seconds));
  lcd_gotolc(1, 11);
  lcd_printInt(bcd_decimal(seconds), 2, true);
  //print_dateAtLine(2, years, months, days);

  SS_SetDigits(minutes >> 4, // 10 hour digit
    minutes & 0x0F, // 1 hour digit
    seconds >> 4, // 10 minute digit
    seconds & 0x0F, // 1 minute digit
    1); // turn on colon
  sei();
}
...

Ergibt eine korrekte Sekundenanzeige auf dem LCD aber auf der 7-Segment 
werden ab Sekunde 10 "04 00" angezeigt. :(

Als weiter Variation habe ich innerhalb der LCD Anzeigefuktion mal an 
sec:sec:sec ausgegeben.
void test_Clock() {

  cli();
  uint8_t hours, minutes, seconds, months, days, years;
  DS1307_GetTime(&hours, &minutes, &seconds);
  //DS1307_GetDate(&years, &months, &days);

  print_timeAtLine(1, bcd_decimal(hours), bcd_decimal(minutes), bcd_decimal(seconds));
  //lcd_gotolc(1, 11);
  //lcd_printInt(bcd_decimal(seconds), 2, true);
  //print_dateAtLine(2, years, months, days);

  SS_SetDigits(minutes >> 4, // 10 hour digit
    minutes & 0x0F, // 1 hour digit
    seconds >> 4, // 10 minute digit
    seconds & 0x0F, // 1 minute digit
    1); // turn on colon
  sei();
}

void print_timeAtLine(uint8_t line, uint8_t hours, uint8_t minutes, uint8_t seconds) {
  //____hh:mm:ss____
  lcd_gotolc(line, 5);
  lcd_printInt(seconds, 2, true);
  lcd_print_P(PSTR(":"));
  lcd_printInt(seconds, 2, true);
  lcd_print_P(PSTR(":"));
  lcd_printInt(seconds, 2, true);

}

Dies bewirkt wie erwartet auf dem LCD eine 3 fach korrekte Anzeige, doch 
steht dann auf dem 7-Segment plötzlich "00 04" bei allen Sekunden größer 
9.

Ist meine printInt denn vielleicht so verkorkst, dass sie etwas 
verrücktes anstellt? Wir sind doch aber eigentlich hier bei C und 
primitiven Datentypen stehts bei Call-By-Value, oder?
void lcd_printInt(uint16_t value, uint8_t c, bool leadingZeros)
{
  char str[c];
  utoa(value, str, 10);
  if(leadingZeros)
  {

    for( uint8_t i = getDigitCount(value); i < c; i++)
      lcd_print_P(PSTR("0"));
  }
  lcd_print(str);
}

Wie könnte ich es komplett zum laufen bekommen bzw. noch detailierter 
debuggen (ohne JTAG nur per Printausgabe/Try-And-Error)?

Grüße Oekel

Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D a v i d K. schrieb:

> Ist meine printInt denn vielleicht so verkorkst, dass sie etwas
> verrücktes anstellt? Wir sind doch aber eigentlich hier bei C und
> primitiven Datentypen stehts bei Call-By-Value, oder?
>
>
> void lcd_printInt(uint16_t value, uint8_t c, bool leadingZeros)
> {
>   char str[c];
>   utoa(value, str, 10);
>   if(leadingZeros)
>   {
> 
>     for( uint8_t i = getDigitCount(value); i < c; i++)
>       lcd_print_P(PSTR("0"));
>   }
>   lcd_print(str);
> }
> 
...
void lcd_print(char *string) {

  while(*string)  {
    lcd_putchar(*string++);
  }
}

schneller Nachtrag: scheinbar ist diese Funktion wirklich schuld, denn 
bei
void print_timeAtLine(uint8_t line, uint8_t hours, uint8_t minutes, uint8_t seconds) {
  //____hh:mm:ss____
//  lcd_gotolc(line, 5);
//  lcd_printInt(hours, 2, true);
//  lcd_print_P(PSTR(":"));
//  lcd_printInt(minutes, 2, true);
//  lcd_print_P(PSTR(":"));
//  lcd_printInt(seconds, 2, true);

  lcd_gotolc(1, 1);
  lcd_printBinary(hours);
  lcd_gotolc(2, 1);
  lcd_printBinary(minutes);
  lcd_printBinary(seconds);

}
Bleibt die 7-Segmentanzeige "sauber" und die Binärwerte laufen auf dem 
LCD munter stetig weiter.

Trotzdem sehe ich den Fehler leider nicht.
Verwende ich "utoa" falsch? Oder hat diese evtl. Seiteneffekte, welche 
ich nicht berücksichtige?

PS: sollte ich einen neuen Thread starten, da es mit dem eigentlichen 
Problem ja nichts mehr zu tun hat. Bzw. das eigentliche Problem ganz 
woanders als in der Überschrift liegt.

: Bearbeitet durch User
Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuche doch einfach mal:
void lcd_printInt(uint16_t value, uint8_t c, bool leadingZeros){
  lcd_print(value/10);
  lcd_print(value%10);
}

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korrektur: print erwartet einen String, das geht nicht.
void print_timeAtLine(uint8_t line, uint8_t h, uint8_t m, uint8_t s){
  //____hh:mm:ss____
  lcd_gotolc(line, 5);
  lcd_putch('0'+h/10);lcd_putch('0'+h%10);lcd_putch(':');
  lcd_putch('0'+m/10);lcd_putch('0'+m%10);lcd_putch(':');
  lcd_putch('0'+s/10);lcd_putch('0'+s%10);
}

Autor: D a v i d K. (oekel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eProfi schrieb:

>
> void print_timeAtLine(uint8_t line, uint8_t h, uint8_t m, uint8_t s){
>   //____hh:mm:ss____
>   lcd_gotolc(line, 5);
>   lcd_putch('0'+h/10);lcd_putch('0'+h%10);lcd_putch(':');
>   lcd_putch('0'+m/10);lcd_putch('0'+m%10);lcd_putch(':');
>   lcd_putch('0'+s/10);lcd_putch('0'+s%10);
> }
> 

das funktioniert in der Tat wunderbar. Vielen DANK!

Wie stehen denn die Chancen den Fehler in meinem lcd_printInt(...) zu 
finden?
Workarrounds sind gut, aber ich möchte ja auch etwas lernen.

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D a v i d K. schrieb:
> OK, es muss etwas mit dem BCD Format zu tun haben.
> Also der Chip funktioniert korrekt, da bin ich mir mittlerweile 100%
> sicher.

logisch und darum nutzen alle DS Uhren die bcd2int

avr gcc z.B. A(VR)- oder Atmel-Studio
uint8_t bcd2int( uint8_t bcd )
{  return ((uint8_t)(((bcd>>4)*10)+(bcd&15)));
} // uint8_t bcd2int( uint8_t bcd )

uint8_t int2bcd( uint8_t integer )
{  return ((uint8_t)(((integer/10)<<4)+(integer%10)));
} // uint8_t int2bcd( uint8_t integer )

in Arduino nutze ich die LIB
die geht mit DS1307 und DS3231 gleichermaßen weil die ersten Register an 
gleicher Stelle liegen
#include <DS1307new.h>


D a v i d K. schrieb:
> Wie stehen denn die Chancen den Fehler in meinem lcd_printInt(...) zu
> finden?

in diesem Code?
> void lcd_printInt(uint16_t value, uint8_t c, bool leadingZeros)
> {
>   char str[c];
>   utoa(value, str, 10);
>   if(leadingZeros)
>   {
> 
>     for( uint8_t i = getDigitCount(value); i < c; i++)
>       lcd_print_P(PSTR("0"));
>   }
>   lcd_print(str);
> }

ich versuchs dann mal

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bevor ich anfange, in diesem Code den ich vorher zeigte?
Beitrag "Re: I2C Real Time Clock/Calendar (DS1337"

warum uint16_t value?
die Uhrzeiten sind eh immer 2-stellig also reicht uint8_t value

sollte mehr dazu kommen wegen uint16_t dann sollte man auch die Ausgbe 
Stellenzahl 2,3,4,5 ? angeben, sowie linksbündig oder rechtsbündig mit 
führende Nullen oder lieber doch führende SPACE?

Die "lcd_printInt" scheint mir nicht universell ausgereift

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.