Hallo Besitzer der Zusatzplatine RP6 CCPRO M128,
die mitgelieferte Library DCF_Lib.cc hat gerade so die basalen Funktionen eines DCF-Decoders. Mit dieser CCPRO BASIC Bibliothek RP6DCFCCLib.cbas wird das besser. Viel Spaß damit.
Demo (DCF_RTC.cbas):Bibliothek (RP6DCFCClib.cbas), Teil 1:Code:/******************************************************************************* * RP6 C-Control PRO M128 Erweiterungsmodul * ---------------------------------------------------------------------------- * DCF_RTC Demoprogramm 2 * ---------------------------------------------------------------------------- * DCF_RTC: DCF Uhr * DCF Empfänger erforderlich * Mega128: DCF-Eingang PE5 (PortE.5, RP6: INT1) * Der DCF-Eingang kann in RP6DCFCClib.cbas geändert werden. * erforderliche Library: IntFunc_Lib.cc und neue RP6DCFCClib.cbas (v. 1.xx). * * Über den zusätzlich erforderlichen DCF Empfänger (Art-Nr. 641138) wird * das DCF Signal empfangen. * Auf dem LCD-Display werden die Zeit und das Datum angezeigt. * Die LED1 blinkt im Sekundentakt. * * Hinweis: * Für allgemeine Programmierhinweise zur CCPRO schauen Sie sich bitte die * CCPRO Dokumentation und die zugehörigen Beispielprogramme an! * Es sei auch nochmals darauf hingewiesen, dass die normalen Beispielprogramme * für die CCPRO nur zum Teil direkt auf dem RP6-CCPRO Modul laufen. * Die Anschlussbelegung ist natürlich komplett anders als auf dem * C-Control Application Board. Auch die LCD Ansteuerung ist leicht anders, * da hier noch zusätzliche LEDs mit an dem Schieberegister angeschlossen sind. * --> Die C-Control Beispielprogramme müssen ein klein wenig angepasst * werden bevor sie auf diesem Modul laufen können! * * ***************************************************************************** * Der Roboter bewegt sich in diesem Beispielprogramm NICHT und kann * am Rechner angeschlossen bleiben! ******************************************************************************/ ' WICHTIG: Immer die RP6CCLib mit einbinden: #include "../../RP6CCLib/RP6CCLib.cbas" ' Die neue RP6DCFCCLib einbinden: #include "../../RP6CCLib/RP6DCFCClib.cbas" Dim irqcnt As Integer ' globale Variablendeklaration Dim cnt1, alte_sekunde As Byte Sub main() ' WICHTIG! Immer als erstes aufrufen: RP6_CCPRO_Init() ' Auf Startsignal warten, LCD und andere Dinge initialisieren ! ' ------------------------------------------------------ ' Zwei Zeilen Text mit dem LCD anzeigen: showScreenLCD("RP6 CCPRO M128", "DCF RTC Demo 2!") ' Zweimal piepsen: beep(200, 300, 100) ' Format: beep (<tonhöhe>, <dauer>, <pause>) beep(100, 100, 100) ' Text über serielle Schnittstelle ausgeben: newline() ' Neue Zeile println(" ________________________") println(" \\| RP6 ROBOT SYSTEM |/") println(" \\_-_-_-_-_-_-_-_-_-_/ ") newline() println(" Let's go! ") newline() ' 2 Sekunden Pause: AbsDelay(2000) ' ------------------------------------------------------ ' DCF-Hauptprogramm: Port_WriteBit(PORT_LED1, PORT_OFF) ' LED1 aus clearLCD() ' Display löschen Time_Init() ' Funktionsaufruf zur Festlegung ' von Startzeit und Startdatum. initDCF() ' Initialisierung des DCF Modus Irq_SetVect(INT_TIM2COMP, INT_10ms) ' ISR definieren ' Timer2: 10ms Interrupt Do While True ' Endlosschleife If cnt1 = 50 Then Port_WriteBit(PORT_LED1, PORT_OFF) ' LED1 aus End If If cnt1 = 100 Then ' Sekundentakt Port_WriteBit(PORT_LED1, PORT_ON) ' LED1 an cnt1 = 0 End If If alte_sekunde <> Sekunde Then alte_sekunde = Sekunde #ifndef DEBUG showCLOCK() ' showSTATUS() #endif #ifdef DEBUG showDEBUGINFO() #endif End If End While End Sub ' ----------------------------------------------------------------------------- ' Festlegung von Startzeit und Startdatum ' Sub Time_Init() Sekunde = 0 ' Uhr Startzeit: 12:00:00 Minute = 0 Stunde = 12 Wochentag = 7 Tag = 31 ' Uhr Startdatum: 31.05.2009 Monat = 5 Jahr = 9 End Sub ' ----------------------------------------------------------------------------- ' Interrupt Routine ' Sub INT_10ms() cnt1 = cnt1 + 1 ' Zähler für Blinken der LED1 decodeDCF() ' DCF77 Decoder irqcnt = Irq_GetCount(INT_TIM2COMP) ' Interrupt Request Counter End Sub ' -----------------------------------------------------------------------------Gruß DirkCode:/* **************************************************************************** * _______________________ * \| RP6 ROBOT SYSTEM |/ * \_-_-_-_-_-_-_-_-_-_/ >>> CCPRO M128 * ---------------------------------------------------------------------------- * ----------------------- [c]2009 - Dirk ------------------------------------- * **************************************************************************** * File: RP6DCFCClib.cbas * Version: 1.0 - CCPRO BASIC * Target: RP6 CCPRO M128 - C-Control PRO M128 @14.7456MHz * mit optionalem LC-Display 16x2 Zeichen (CONRAD 190911) * [oder OLED Textdisplay 16x2 Zeichen (CONRAD 197622)] * und einem DCF77 Empfänger Modul (z.B. CONRAD 641138) * Author(s): Dirk * **************************************************************************** * Beschreibung: * Dies ist meine DCF77 Bibliothek für die RP6 CCPRO M128. * Der DCF-Empfänger wird an PE5 (XBUS INT1, SPI_I/O: Pin 7) der CCPRO M128 * angeschlossen. * * ANMERKUNG: Ein 10 kOhm Pulldown-Widerstand (R34) ist auf dem RP6 Mainboard * mit E_INT1 verbunden und damit auch mit INT1 auf der CCPRO M128. * Normalerweise haben DCF Empfänger einen open-collector Ausgang * und benötigen einen PULLUP Widerstand zur korrekten Funktion. * Der interne Pullup-Widerstand des ATMEGA128 kann den Pulldown- * Widerstand auf dem RP6 Mainboard nicht kompensieren. * Deshalb muss man einen PULLUP-Widerstand zwischen +5V und den * DCF Empfängerausgang legen. Bei meinem DCF Empfänger klappt es * gut mit einem 2,2 kOhm Widerstand. * * **************************************************************************** * CHANGELOG FINDEN SIE AM ENDE DIESER DATEI! * **************************************************************************** */ ' Alles nur EINMAL einbinden! #ifndef __RP6DCFCCLIB__ #define __RP6DCFCCLIB__ /******************************************************************************/ ' Defines: ' RP6 CCPRO M128 DCF Empfänger Anschluß: #define DCF_IN 37 ' DCF Eingangs Signale an PortE.5 (RP6: INT1) ' #define DCF_IN 13 ' DCF Eingangs Signal an PortB.5 (SERVO_1 PB5) #define BIT_0 0x00 ' 0b00000000 #define BIT_1 0x80 ' 0b10000000 #define LETZTESBIT_0 0x40 ' 0b01000000 #define LETZTESBIT_1 0xc0 ' 0b11000000 #define BIT_FEHLER 0x01 ' 0b00000001 /**************************************************************/ ' AUFBAU DES DCF77 TELEGRAMMS: ' Bit 0: DCF Bit 0 (immer 0) ' Bits 1..14: Codierte Wetter Infos (Meteo Time GmbH) ' Bits 15..20 (DCF Flags): ' Flag R: Ruf Bit 15 für PTB Angestellte ' Flag A1: Ankündigung eines Zeitzonenwechsels ' Flag Z1: Zeitzone 1 [0 = MEZ, 1 = MESZ] (Z1 != Z2) ' Flag Z2: Zeitzone 2 [1 = MEZ, 0 = MESZ] (Z2 != Z1) ' Flag A2: Ankündigung einer Schaltsekunde ' Flag S: Start Bit 20 (immer 1) ' Bits 21..27: Minute (BCD) ' Bit 28 [P1]: Minutenparität ' Bits 29..34: Stunde (BCD) ' Bit 35 [P2]: Stundenparität ' Bits 36..41: Tag (BCD) ' Bits 42..44: Wochentag ' Bits 45..49: Monat (BCD) ' Bits 50..57: Jahr (BCD) ' Bit 58 [P3]: Datumsparität ' [Bit 59: Schaltsekundenbit (immer 0)] /**************************************************************/ ' #define DEBUG ' Debug Modus ' Der Debug Modus dient zum Abgleich der Pausenlängen (PAUSE_xxxMS). ' Das LCD zeigt die vom Decoder erkannten Pausenlängen an. Wenn es ' eine deutliche Abweichung gibt, können die Pausenlängen angepaßt ' werden. ' #define REPARATUR ' Reparatur Modus ' Im Reparatur Modus wird in dieser Programm Version nur eine Er- ' kennung von Spikes ermöglicht. Damit sinkt die Störanfälligkeit. ' In weiteren Programmversionen kann hier ggf. noch eine "echte" ' Reparatur von fehlerhaften DCF Telegrammen erfolgen. ' #define WETTER ' Wetter Infos decodieren ' Wenn man die in den DCF Bits 1..14 enthaltenen Wetter Informationen ' einsehen möchte, muss man das Programm mit definiertem "WETTER" ' kompilieren. Da die Infos verschlüsselt sind, wird man in der Regel ' diese Bits nicht sinnvoll verwenden können. #define UHRABGLEICH 100 ' Uhr Abgleich (100 x 10ms = 1s) ' Mit "UHRABGLEICH" kann man die Ganggenauigkeit der Software-Uhr beein- ' flussen. #define PAUSE_800MS 80 ' Bit 1 Pausenlänge #define PAUSE_900MS 90 ' Bit 0 Pausenlänge #define PAUSE_1800MS 180 ' Letztes Bit 1 Pausenlänge #define PAUSE_1900MS 190 ' Letztes Bit 0 Pausenlänge #define PAUSE_ABWEICHUNG 5 ' Pausenlänge Abweichung ' Das DCF77 Telegramm wird in einer ganzen Minute für die Folgeminute ' übertragen. In jeder Sekunde wird ein DCF Bit codiert. Senderseitig ' wird dazu die Sendeleistung 100ms lang für ein 0-Bit oder 200ms lang ' für ein 1-Bit auf 25% abgesenkt. Danach ist für den Rest der Sekunde ' (900ms bzw. 800ms) Pause, also 100% Sendeleistung. Für einen DCF De- ' coder ist das Ende des Telegramms dadurch erkennbar, dass das letzte ' Bit (DCF Bit 58) eine Pause von 1900ms bzw. 1800ms besitzt. Damit ' können die o.g. 4 Pausendauern (PAUSE_XXXMS) unterschieden werden. ' Da der DCF Decoder alle 10ms aufgerufen wird, wird er etwa 80-mal den ' selben Pegel am Eingang feststellen, wenn die Pause nach einem 1-Bit ' gesendet wird. ' Durch "PAUSE_ABWEICHUNG" wird festgelegt, welche Abweichung vom Soll ' zugelassen wird. Beim Wert 5 erkennt der Decoder ein 1-Bit, wenn er ' zwischen 75- und 84-mal (= 750..840ms) den selben Pegel feststellt. #define VALIDITAETSSTANDARD 1 ' Validitätszähler Grenze ' (1: Jedes DCF Telegramm nutzen!) ' Als INTAKT gilt ein Telegramm, wenn folgende Bedingungen erfüllt sind: ' 1. DCF Bit 0 ist 0 ' 2. DCF Bits 17 und 18 sind ungleich ' 3. DCF Bit 20 ist 1 ' 4. Die Paritätsbits 28, 35, 58 enthalten eine korrekte gerade Parität ' 5. Es wurden genau 58 DCF Bits decodiert ' 6. Fall Schaltsekunde: DCF Bit 59 ist 0 und DCF Bit 19 ist 1 ' Nicht PLAUSIBEL ist ein Telegramm, wenn Werte außerhalb des möglichen ' Bereichs liegen. Ein Wert von 9 für den Wochentag ist z.B. nicht ' plausibel. Allgemeiner könnte man sagen, dass ein DCF Telegramm nicht ' plausibel ist, wenn es nicht die Folgeminute der aktuellen Minute ab- ' bildet. ' Ein Telegramm ist VALIDE (= gültig), wenn es intakt UND plausibel ist. ' Jedes valide DCF Telegramm wird gezählt. Ist VALIDITAETSSTANDARD 1, ' dann wird jedes valide Telegramm zum Stellen der Uhr verwendet. Man ' kann den Wert erhöhen, wenn man ein Stellen der Uhr nur bei sehr guten ' Empfangsbedingungen erlauben will. Setzt man VALIDITAETSSTANDARD z.B. ' auf 3, dann wird ein Telegramm nur dann zum Stellen der Uhr verwendet, ' wenn es das dritte valide Telegramm in Folge ist. /******************************************************************************/ ' Variablen: Dim Jahr As Byte ' Jahr [0..99] Dim Monat As Byte ' Monat [1..12] Dim Wochentag As Byte ' Wochentag [1..7 = MO..SO] Dim Tag As Byte ' Tag [1..31] Dim Sommerzeit As Byte ' Zeitzone [0 / 1 = MEZ / MESZ] Dim Stunde As Byte ' Stunde [0..23] Dim Minute As Byte ' Minute [0..59] Dim Sekunde As Byte ' Sekunde [0..59] #ifdef WETTER Dim Wetter As Word ' Codierte Wetter Informationen #endif ' (DCF Bits 1..14; Bit 0 immer 0) Dim dcfflags As Byte ' DCF Flags (DCF Bits 15..20): #define FLAG_R 1 ' R: Ruf Bit 15 für PTB Angestellte #define FLAG_A1 2 ' A1: Ankündigung eines Zeitzonenwechsels #define FLAG_Z1 4 ' Z1: Zeitzone 1 [0 = MEZ, 1 = MESZ] #define FLAG_Z2 8 ' Z2: Zeitzone 2 [1 = MEZ, 0 = MESZ] #define FLAG_A2 16 ' A2: Ankündigung einer Schaltsekunde #define FLAG_S 32 ' S: Start Bit 20 (immer 1) Dim dcfstatus As Byte ' Status Flags (Bits 0..5 nur lesen!): #define STATUS_FEHLER 1 ' Telegramm Fehler #define STATUS_MINPARITAET 2 ' Minutenparität ok #define STATUS_STDPARITAET 4 ' Stundenparität ok #define STATUS_DATPARITAET 8 ' Datumsparität ok #define STATUS_DCFBIT58 16 ' 58 (oder 59) DCF Bits decodiert #define STATUS_TELEGRAMMINTAKT 32 ' Telegramm intakt #define STATUS_UHRGESTELLT 64 ' Uhr einmal gestellt #define STATUS_DCF_AN 128 ' DCF77 Decoder AN Dim validitaetszaehler As Byte ' Zähler für intakte und ' plausible DCF Telegramme Dim validitaetsgrenze As Byte ' Grenze Validitäts Zähler #ifdef DEBUG Dim pause_1_laenge As Byte Dim pause_0_laenge As Byte Dim letztepause_1_laenge As Byte Dim letztepause_0_laenge As Byte #endif /******************************************************************************/ ' Funktionen: /** * INIT DCF * * Unbedingt einmal aufrufen, bevor die DCF77 Funktion benutzt wird! * */ Sub initDCF() Port_DataDirBit(DCF_IN, 0) ' Port = Eingang Port_WriteBit(DCF_IN, 1) ' Pullup Widerstand ein validitaetszaehler = 0 ' Validitätszähler zurücksetzen validitaetsgrenze = VALIDITAETSSTANDARD ' Grenze setzen dcfstatus = STATUS_DCF_AN ' DCF77 Decoder AN End Sub /** * DCF DECODER AN * * Der DCF77 Decoder wird eingeschaltet. * Immer wenn ein intaktes DCF Telegramm decodiert wurde, kann die * Uhr mit den aktuellen DCF Informationen gestellt werden. * */ Sub DCFon() dcfstatus = dcfstatus Or STATUS_DCF_AN ' Status Bit 7 setzen End Sub /** * DCF DECODER AUS * * Der DCF77 Decoder wird ausgeschaltet. * Die Uhr wird durch die interne Referenz (Timer) betrieben. * */ Sub DCFoff() ' Alle Status Bits löschen, nur Status Bit 6 bleibt unverändert: dcfstatus = dcfstatus And STATUS_UHRGESTELLT End Sub /** * BCD to DEC * * Diese Funktion wandelt einen BCD- in einen Dezimalwert um. * */ Sub BCDtoDEC(bcd As Byte) As Byte Return (bcd >> 4) * 10 + (bcd And 0x0f) End Sub
P.S.: Teil 2 der Bibliothek folgt!
Lesezeichen