Forum: Mikrocontroller und Digitale Elektronik MSP430F1612_RTC_Display


von Mathias U. (Gast)


Lesenswert?

Hallo ich bin gerade am Bearbeiten eines etwas größeren Projektes mit 
dem MSP430F1612.

Ich habe die Sache in Teilaufgaben aufgeteilt, damit ich Euch nicht mit 
den einzelheiten langweile... ;-)

Folgendes Problem möchte ich jetzt lösen:

Ausgabe der Uhrzeit und des Datums auf einem 2*20 Zeichen-LCD.

Ich möchte die Sache per Software realisieren, weil ich die Hardware 
soweit fertig habe. Also eine RTC in Hardware kommt nicht in Frage.

Am Xin ist beim MSP ein 32768Hz Quarz angeschlossen.

TI hat ja eine schicke Bibliothek im Angebot: die RTC.h bzw. die 
RTC_Calendar.h und weitere...

Diese möchte ich benutzen.

Als Software wird IAR ew 3.20A benutzt.

Ich habe probeweise mal nur die Uhrzeit getestet, aber es taucht ein 
kleines problem auf, bei dem ich im Moment nicht weiterweiß.
Hier mal der Code:
1
#include "owndef.h"
2
#include "lcd.h"
3
#include "port_def.h"
4
5
#include "RTC.h"
6
#include "RTC_TA.h"
7
8
#if( LCD_VERSION != 0x0100 )
9
  #error "Falsche LCD Version"
10
#endif
11
12
void main()
13
{
14
// ************************************************************************************************
15
// definition lokaler variablen
16
// ************************************************************************************************
17
// ************************************************************************************************
18
19
  WDTCTL=WDTPW+WDTHOLD; // stoppt den WDT
20
21
  port_def();           // aufruf der fkt. port_def() für definition der ports
22
    
23
// ************************************************************************************************
24
//initialsierung lcd
25
// ************************************************************************************************     
26
  LCD_Init();           // LCD initialisieren ...
27
  LCD_Clear();          // ... dann loeschen und cursor an anfang, cursor wird autom. erhöht
28
// ************************************************************************************************
29
30
  setTime( 0x12, 0, 0, 0);                          // initialize time to 12:00:00 AM
31
  TA_1sec_wake();                                   // configure TA for 1 second update
32
  //LPM3;                                             // enter LPM3, clock will be updated
33
                                                        
34
  for (;;)                                          // beginn endlosschleife for(;;)
35
  {
36
  LCD_Cursor_Set(0,0);                              // anfang zeile 1
37
  LCD_Awrite("ich bin ein display.");               // string ausgeben
38
  LCD_Cursor_Set(1,0);                              // anfang zeile 2
39
  LCD_Zahl(TI_hour,2,0);                            // stunde ausgeben
40
  LCD_Awrite(":");                                  // string ausgeben
41
  LCD_Zahl(TI_minute,2,0);                          // minute ausgeben
42
  LCD_Awrite(":");                                  // string ausgeben
43
  LCD_Zahl(TI_second,2,0);                          // sekunden ausgeben
44
45
 } // ende endlosschleife for (;;)
46
}  // ende main

Den Code für die erhöhung der Sekunden, und damit der ganzen Zeit, habe 
ich dem ApNote SLAA290 von TI entnommen.
Den LPM3 habe ich auskommentiert, weil ich (noch) nicht möchte, dass der 
MSP sich schlafen legt.

Es wird eine Uhrzeit auf dem Display angezeit, jedoch ist diese 
fehlerbehaftet.

Laut ApNote werden alle Variablen der RTC.h usw. als BCD encoded.
Die Sekunden, sowie die Minuten und die Stunden werden nicht richtig 
"hochgezählt". Z.B. gehen die Sekunden bis 89 hoch, erst dann werden die 
Minuten hochgezählt. Auch lässt er dabei einige Sekunden aus.
89dezimal sind 59hex. Da wird das Problem liegen.
Das Display zeigt es dezimal an, aber intern wird mit Hex gearbeitet.

Ich initialisiere ja die Zeit mit 0x12...auf dem Display erscheint 
18Uhr...klar, weil 12hex = 18dezimal...

Hat jemand eine Idee, wie ich das auf einfache Art lösen könnte?

Ich nehme mal an, das Problem wird dann beim Datum genauso auftauchen...
Der nächste Schritt wäre dann, dass ich per Taster die Uhrzeit manuelle 
einstellen kann, aber erstmal eins nach dem anderen...

Es wäre schön, wenn mir jemand ein paar Hilfestellungen geben würde.

Danke

von Uhu U. (uhu)


Lesenswert?

Da du den Code der ISR weggelassen hast, der für das Hochzählen der Zeit 
verantwortlich ist, kann man zu deinem Problem leider nur sagen, daß man 
nichts dazu sagen kann...

Länglichen Code bit als Datei-Anhang posten!

von Mathias U. (Gast)


Lesenswert?

Hmm...

"In the example above, the writer chose to implement their own Timer_A 
Interrupt Service
Routine (ISR), and set up Timer_A for a 1 second interrupt. If they did 
not want to write their
own ISR and were using a 32.768kHZ crystal, they could have used the 
RTC_TA library:"

Genau das habe ich gemacht...Die ISR steht in der TRC_TA.s43.
Hab sie mal angehangen...

von Mathias U. (munter)


Angehängte Dateien:

Lesenswert?

...jetzt mit Anhang...

von Mathias U. (munter)


Lesenswert?

Guten Morgen,

hat denn keiner eine Idee?

Ich bin programmiertechnisch nicht der allergrößte Freak (newbie 
halt...), und mit Assambler hab ich gar nichts am Hut.

Es wäre toll, wenn sich jemand meinem Problem annehmen würde.

Bitte... :-)

von Jörg S. (Gast)


Lesenswert?

Mein Vorschlag: Die RTC Funktion auf Watchdog Interrupt umbauen. Dazu 
gibt es von TI und hier im Forum Beispiele für.

von Mathias U. (munter)


Lesenswert?

Danke, aber das bringt leider gar nichst.
Es tritt das gleiche Phänomen wie beim Timer_A auf...

Ich habe das WDT_examample.c von TI genommen...sieht ja fast genauso 
aus, wie das Beispiel mit dem Timer_A.
1
#include  <msp430x14x.h>
2
#include  "RTC.h"
3
#include  "RTC_WDT.h"
4
5
6
void main ( void )
7
{
8
  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
9
  setTime( 0x12, 0, 0, 0);              // initialize time to 12:00:00 AM
10
  WDT_1sec_wake();                      // configure WDT for 1 second update
11
  LPM3;                                 // enter LPM3, clock will be updated
12
13
}
Nur das ich wieder den LPM3 auskommentiere, und meine Anzeige aufm 
Display mache...

Das Problem liegt sicher bei der Anzeige, und wie er "intern" hochzählt.

Im SLAA290 steht drin:
"To be easily displayable on an LCD all variables are encoded in BCD."

Ich denke, ich muss *einfach nur diese BCD Werte in dezimal wandeln, 
aber wie?

Ich habe mal eine Excel-Tabelle gemacht, mit Hex-Werten, die immer um 1 
erhöht werden, also
0 1 2 3 4 5 6 7 8 9 10 11 12 13 usw.
Dazu dann die dezimalen Werte
0 1 2 3 4 5 6 7 8 9 16 17 18 19 usw...

Das geht dann halt so weiter bis 0x59 und das sind 89dezimal.
Wenn das Display die 89ste Sekunde anzeigt, dann springt danach die 
Minute eins höher und die Sekunden wieder auf Null.
--> Also irgendein Anzeige/ Umwandlungsproblem...

Was kann ich da machen?
Danke

von Uhu U. (uhu)


Lesenswert?

Mathias U. wrote:
> ...jetzt mit Anhang...

Das ist zwar die ISR, aber der Kandidat, der für das Zeitzählen 
verantwortlich ist, heißt incrementSeconds und ist in dem Anhang leider 
nicht enthalten. incrementSeconds wird in der ISR per call aufgerufen.

von Mathias U. (munter)


Angehängte Dateien:

Lesenswert?

Da haste wohl recht...

Jetzt aber.

von Uhu U. (uhu)


Lesenswert?

Tja, des Rätsels Lösung ist sehr einfach: Die Daten sind BCD-codiert. 
Die Reihe sieht so aus:

      0     1     2     3  ...    9
   0x00, 0x01, 0x02, 0x03, ... 0x09

     10    11    12    13        14
   0x10, 0x11, 0x12, 0x13, ... 0x19

   usw. usf.

Vermulich frißt aber deine LCD_Zahl binärcodierte Werte. Sie 
interpretiert die BCD-Daten also falsch.

von Mathias U. (munter)


Lesenswert?

Danke, aber wo ist jetzt die Lösung?
Das es sicher höchstwahrscheinlich um ein Interprätations-/ 
Umwandlungsproblem handelt, hatte ich mir schon gedacht. ;-)

Wie krieg ich es jetzt hin, dass mein LCD die BCD-Daten versteht?
Ich muss sie sicherlich umwandeln, aber wie mach ich das am schlauesten?
(möglichst in C)

Ich find es auch unschön, dass er dann die Umwandlung jede Sekunde 
machen muss. Es wäre natürlich schöner, weil effektiver, wenn die Daten 
gleich als binärcodiert ankommen würden.
Aber da ich in Assambler ne absolute Null bin, wird das für mich eher 
schwierig...

von Fritz (Gast)


Lesenswert?

Hallo,

ich habe einmal auf einem MSP430F149 die RTC von TI ans Laufen gebracht. 
Das war eigentlich recht einfach. Ich habe die uhrzeit und das datum 
auch auf einem 4*20 Zeichen Display ausgeben lassen. Ist schon eine 
weile her, deswegen stecke ich da nicht mehr so drin.

Es gibt da aber so weit ich mch erinnere funktionen, mit denen man die 
Stunde Sekunde usw. ermitteln kann. Die zahlen liegen dann ja als hex 
vor 0x00 bis 0x59 z.B. Die muss man dann natürlich noch in int 
umwandeln.

Ich habe die Ausgabe der Zeit und des datums in eine eigene Funktion 
gepackt. Die rufe ich einmal in der Sekunde auf. Darin hole ich mir dann 
die aktuellen Daten und gebe diese aus.

Der folgende Code dient in dieser Funktion zum ermiteln der aktuellen 
Daten  und zur Umwandlung von Hex in Dez.
1
void ShowTime(int sec)
2
{
3
  StundeZehner= (get24Hour() >> 4) + 0x30;  // Umwanlung der Hexzahlen in Int
4
  StundeEiner= (get24Hour() & 0x0F) + 0x30;   
5
  MinuteZehner= (TI_minute >> 4) + 0x30;
6
  MinuteEiner= (TI_minute & 0x0F) + 0x30;
7
  SekundeZehner= (TI_second >> 4) + 0x30;
8
  SekundeEiner= (TI_second & 0x0F) + 0x30;    
9
  // get24Hour() liefert die Stunde im 24 Stunden Format 
10
11
  Stunde=StundeZehner*10+StundeEiner-16;    // Zusammensetzen der Einer und 
12
                                            // Zehner in eine Variable
13
  .....
14
  ausgabe auf dem display
15
}

Auch wenns ein wenig durcheinander ist, vielleicht hilfts dir ja weiter.

Grüße
Fritz

von Uhu U. (uhu)


Lesenswert?

Im Prinzip funktioniert die Wandlung BCD -> binär genauso, wie eine 
ASCII -> Binärwandlung, nur daß ein Zeichen nicht 8 Bit, sondern nur 4 
bit lang ist.

Ich weiß, das ist jetzt auch keine fertige Lösung, aber die sollst ja du 
finden ;-)

von Mathias U. (munter)


Lesenswert?

Dankeschön!
Nach benutzen der Forumsuche ;-) hab ich auch ne Menge Infos gefunden.
Jetzt funktioniert es.

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.