Advertisement
Christof_Ermer

DCF CLOCK New Version 12.2019

Dec 16th, 2019
848
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 42.84 KB | None | 0 0
  1. /*
  2. ALLEIN Noch nicht lauffähig.
  3. Module müsen separiert und in eigens Projekt iengefügt werden.
  4. Geschrieben für WINAVR bzw GCC für AVR Controller
  5.  
  6. ------------------------------------------------------------------------------
  7. DCF CLOCK My New Version
  8. für das Pollin DCF Modul, bzw jedes Andere, dass 100, 200 ms Flanken  High-Low Produziert
  9. 12.2019
  10. Programmed by Christof Ermer
  11. ------------------------------------------------------------------------------
  12. */
  13. /*
  14. DCF Uhr: Neue Konzepte und Ursource von Ulrich Radig. Inzwischen jedoch völlig verändert-
  15. Unfertig. Weatherdaten Decoding, weil geheim.  Aber mit Separation der Daten
  16. TWO PARTS
  17. HEADER UND  ANSI_C SOURCE
  18. 1. HEADER
  19. 2. C_SOURCE
  20. 3. MAIN: Abschnitt .H +.C
  21. Unsiniges selbst rauslöschen
  22. Darin Enthalten
  23. I2C LCD, I2C OCF8571 LED LEiste, DAC ,mit LTC
  24.  
  25. */
  26.  
  27.  
  28. /*
  29. 24.11.2019
  30. Christof Ermer
  31. Umgeschrieben für ATMega328p Arduino UNO
  32.  
  33. Interrupt geändert von INTo auf INT1
  34.  BENUTZE INT1
  35. ICH BENUTZE DEN INT1 fuer das POLLIN DCF
  36. Auschalten PON Rausgewrofen
  37. PON = GND
  38. VCC= 3.3V !!!!!
  39.  
  40. https://xdec.de/msp430-dcf77-empfang-und-auswertung/
  41.  
  42. GETESTED NUR mit ATMEGA16
  43. */
  44.  
  45. /*#######################################################################################
  46. AVR DCF77 Clock
  47.  
  48. Copyright (C) 2005 Ulrich Radig
  49.  
  50. //Änderungen: Christof Ermer Regensburg
  51. Pollin DCF...
  52. Umstellung auf INT1
  53. gu32DCF_msTimerSync
  54. gu32MS_NOW
  55. #######################################################################################*/
  56.  
  57. #ifndef _POLLIN_CLOCK_H
  58.  #define _POLLIN_CLOCK_H
  59.  
  60. #define SETBOP  |=
  61. #define CLRBOP  &= ~
  62.  
  63. #define DCF_BEEP_DDRX   DDRD
  64. #define DCF_BEEP_PORT   PORTD
  65. #define DCF_BEEP_BIT    (1<<PD4)
  66.  
  67. #define BEEP_INIT() (DCF_BEEP_DDRX |= DCF_BEEP_BIT)
  68. #define BEEP_ON()   (DCF_BEEP_PORT |= DCF_BEEP_BIT)
  69. #define BEEP_OFF()  (DCF_BEEP_PORT &= ~DCF_BEEP_BIT)
  70.  
  71. #define BEEP_KNACKS_MS  5
  72. #define BEEP_SHORT_MS   25
  73. #define BEEP_LONG_MS    100
  74. #define BEEP_PAUSE      3
  75.  
  76. #define DCF_NULL_TIME   950
  77.  
  78. #define DEBOUNCE_TO_SHORT_MS    90
  79. //250 Ticks/Sekunde = 0,25 Tick/milisekunde
  80.  
  81. #define DCF_Sec_Puls    0x01
  82. #define DCF_INT_SEC     0x02
  83. #define DCF_RISING_INT  0x04
  84. #define DCF_FALLING_INT 0x08
  85. #define DCF_SYNC        0x10
  86. // --
  87. #define DCF_DETECT_L    0x40
  88. #define DCF_DETECT_H    0x80
  89. //volatile uint8_t  gu8DCF_Status;
  90.  
  91. #define DCF_NOSIGNAL_TIMEOUT 2300
  92.  
  93.  
  94. //Ausschalten wenn nicht benötigt
  95.  
  96. #define POLLIN_DCF // USER BESTIMMTE HARDWARE SELBST ANPASSEN
  97. #ifdef POLLIN_DCF
  98. /*
  99. #define PON      (1<<PD4)
  100. #define DCF_PORT            PORTD
  101. #define DCF_DIRECTION_PORT  DDRD
  102. #define DCF_DDR_INIt()  (DCF_DIRECTION_PORT |= PON)
  103. #define DCF_STOP()      (DCF_PORT |= PON)   //DCF AUSSCHALTEN
  104. #define DCF_RUN()       (DCF_PORT &= ~PON)  //DCF EINSCHALTEN
  105. // ~1Sec.
  106. Erledigt 10µF an 10K Integrator
  107. */
  108.  
  109. #define DCF_INTX_PORTX          PORTD
  110. #define DCF_INTX_DDRX           DDRD
  111. #define DCF_INTX_DATA_BIT       (1<<PD3)  //INT1
  112. #define DCF_INTX_DDRX_INIT()    (DCF_INTX_DDRX &= ~DCF_INTX_DATA_BIT)
  113. #endif
  114.  
  115.  
  116. // =================================================================
  117.  
  118.  
  119. //Interface
  120. //#define USE_INT0
  121. #define USE_INT1
  122.  
  123. #if defined (__AVR_ATmega328P__)   
  124.  
  125. #define INTX_EDGE_CTRL_REG EICRA
  126.  
  127. #ifdef  USE_INT0
  128.     #define DCF77_INT_VECT      INT0_vect
  129.     #define DCF77_INT_ENABLE()  (EIMSK |= (1<< INT0));
  130.     #define DCF77_INT_DISABLE() (EIMSK &= ~(1<< INT0));
  131.     #define CLEAR_INTX_FLAG()       (EIFR = (1<<INTF0))     // MIT "=" 
  132.     #define INT_X_EDGE_MASK         ((1<< ISC01) | (1<< ISC00))
  133.     #define INT_X_FALLING_EDGE_BITS (1<< ISC01)
  134.     #define INT_X_RISING_EDGE_BITS  ((1<< ISC01) | (1<< ISC00))
  135. //#endif
  136.  
  137. //#ifdef USE_INT1
  138. #else
  139.     #define DCF77_INT_VECT      INT1_vect
  140.     #define DCF77_INT_ENABLE()  (EIMSK |= (1<< INT1));
  141.     #define DCF77_INT_DISABLE() (EIMSK &= ~(1<< INT1));
  142.     #define CLEAR_INTX_FLAG()       (EIFR = (1<<INTF1))     // MIT "=" 
  143.     #define INT_X_EDGE_MASK         ((1<< ISC11) | (1<< ISC10))
  144.     #define INT_X_FALLING_EDGE_BITS (1<< ISC11)
  145.     #define INT_X_RISING_EDGE_BITS  ((1<< ISC11) | (1<< ISC10))
  146. #endif
  147.  
  148.     #define INT_X_FALLING_EDGE()    (EICRA = ((EICRA & ~INT_X_EDGE_MASK) | INT_X_FALLING_EDGE_BITS))
  149.     #define INT_X_RISING_EDGE()     (EICRA = ((EICRA & ~INT_X_EDGE_MASK) | INT_X_RISING_EDGE_BITS))
  150.     //TIMSK1 = bit (TOIE1);
  151. #endif //(__AVR_ATmega328P__)  
  152.  
  153. #if defined (__AVR_ATmega16__)
  154.     //Interrupt an dem das DCF77 Modul hängt hier INT1
  155.     #define DCF77_INT_ENABLE()  GICR |= (1<<INT1);
  156.     #define DCF77_INT_DISABLE() GICR &= ~(1<<INT1);
  157.     #define DCF77_INT           INT1_vect //SIG_INTERRUPT1
  158.     #define INT1_CONTROL        MCUCR
  159. //RICHTIG
  160.     //#define INT0_FALLING_EDGE 0x02
  161.     //#define INT0_RISING_EDGE  0x03
  162. //RICHTIG
  163.     #define INT1_FALLING_EDGE   0x08
  164.     #define INT1_RISING_EDGE    0x0C
  165.     #define TIMSK1              TIMSK
  166. #endif
  167.  
  168. #if defined (__AVR_ATmega32__)
  169.     //Interrupt an dem das DCF77 Modul hängt hier INT1
  170.     #define DCF77_INT_ENABLE()  GICR |= (1<<INT1);
  171.     #define DCF77_INT_DISABLE() GICR &= ~(1<<INT1);
  172.     #define DCF77_INT           INT1_vect
  173.     #define INT1_CONTROL        MCUCR
  174.     #define INT1_FALLING_EDGE   0x08    // 0x02
  175.     #define INT1_RISING_EDGE    0x0C    //0x03
  176.     #define TIMSK1              TIMSK
  177. #endif
  178.  
  179. #if defined (__AVR_ATmega8__)
  180.     //Interrupt an dem das DCF77 Modul hängt hier INT1
  181.     #define DCF77_INT_ENABLE()  GICR |= (1<<INT1);
  182.     #define DCF77_INT_DISABLE() GICR &= ~(1<<INT1);
  183.     #define DCF77_INT           INT1_vect
  184.     #define INT1_CONTROL        MCUCR
  185.     #define INT1_FALLING_EDGE   0x08
  186.     #define INT1_RISING_EDGE    0x0C
  187.     #define TIMSK1              TIMSK
  188. #endif
  189.  
  190. #if defined (__AVR_ATmega88__)
  191.     //Interrupt an dem das DCF77 Modul hängt hier INT1
  192.     #define DCF77_INT_ENABLE()  EIMSK |= (1<<INT1);
  193.     #define DCF77_INT_DISABLE() EIMSK &= ~(1<<INT1);
  194.     #define DCF77_INT           INT1_vect
  195.     #define INT1_CONTROL        EICRA
  196.     #define INT1_FALLING_EDGE   0x08
  197.     #define INT1_RISING_EDGE    0x0C
  198. #endif
  199.  
  200.  
  201. //http://www.c-howto.de/tutorial/strukturierte-datentypen/bitfelder/
  202.  
  203. //Structur des gu64DCF_rx_buffer
  204. typedef struct
  205.     {
  206.     unsigned char M             :1  ;
  207.     unsigned int Weather        :14 ;
  208. /*
  209.     unsigned char O1            :1  ; //Weather
  210.     unsigned char O2            :1  ;   //Kodierung nach Bedarf
  211.     unsigned char O3            :1  ;
  212.     unsigned char O4            :1  ;
  213.     unsigned char O5            :1  ;
  214.     unsigned char O6            :1  ;
  215.     unsigned char O7            :1  ;
  216.     unsigned char O8            :1  ;
  217.     unsigned char O9            :1  ;
  218.     unsigned char O10           :1  ;
  219.     unsigned char O11           :1  ;
  220.     unsigned char O12           :1  ;
  221.     unsigned char O13           :1  ;
  222.     unsigned char O14           :1  ;
  223. */  unsigned char R             :1  ;
  224.     unsigned char A1            :1  ;
  225.     unsigned char Z1            :1  ;
  226.     unsigned char Z2            :1  ;
  227.     unsigned char A2            :1  ;
  228.     unsigned char S             :1  ;
  229.     unsigned char Min           :7  ;//7 Bits für die Minuten
  230.     unsigned char P1            :1  ;//Parity Minuten
  231.     unsigned char Hour          :6  ;//6 Bits für die Stunden
  232.     unsigned char P2            :1  ;//Parity Stunden
  233.     unsigned char Day           :6  ;//6 Bits für den Tag
  234.     unsigned char Weekday       :3  ;//3 Bits für den Wochentag
  235.     unsigned char Month         :5  ;//3 Bits für den Monat
  236.     unsigned char Year          :8  ;//8 Bits für das Jahr **eine 5 für das Jahr 2005**
  237.     unsigned char P3            :1  ;//Parity von P2
  238.     }DCF77_BITS_TYPE;
  239.    
  240. typedef union
  241.     {
  242.     DCF77_BITS_TYPE bitRx_Buffer;
  243.     uint64_t u64DCF_RxBuffer; //ull
  244.     }DCF77_UNION_T;
  245.  
  246. typedef struct
  247.     {
  248.     volatile char parity_err    :1;//0 Hilfs Parity
  249.     volatile char parity_P1     :1;//1 Berechnetes Parity P1
  250.     volatile char parity_P2     :1;//2 Berechnetes Parity P2
  251.     volatile char parity_P3     :1;//3 Berechnetes Parity P3
  252.     volatile char dcf_rx        :1;//4 Es wurde ein Impuls empfangen
  253.     volatile char dcf_sync      :1;//5 In der letzten Minuten wurde die Uhr syncronisiert
  254.     volatile char dcf_NoSignal  :1;//6  
  255.     volatile char dcf_SecPuls   :1;//7  
  256.     volatile uint8_t dcf_WeatherSquCnt :2; // 0=Nothing 1..2..3
  257.  
  258.     volatile char dcf_Plip      :1;//8  1== sec
  259.     volatile char dcf_Beep      :1;//9  1== sec in Int erledigt
  260.     volatile char dcf_BeepLong  :1;//10     1== sec in Int erledigt
  261.     }ST_DCF_FLAGS_TYPE;
  262.     //gstDCF_Flags;
  263.    
  264. typedef struct
  265.     {
  266.     unsigned char Tag   :4; //0..3
  267.     unsigned char Nacht :4; //4..7
  268.     unsigned char HeavyWheather :4; //8..11
  269.     //Bit 15=0  aktueller Tag B15=1
  270.     unsigned char Regenwahrsch  :3; //12..14
  271.     unsigned char SwitchBit_8_11    :1; //15
  272.     unsigned char Temperatur :6; //16.21
  273.     unsigned char Prognose_Tag  :4;
  274.     unsigned char Prognose_Nacht :4;
  275.    
  276.    
  277.     }DCF_WEATHERTYPE;
  278.  
  279.  
  280. //64 Bit für DCF77 benötigt werden 59 Bits
  281. //RX Pointer (Counter)
  282.  
  283. extern volatile ST_DCF_FLAGS_TYPE gstDCF_Flags;
  284. extern volatile DCF77_UNION_T gstunDCF77_Bits; // union Struct
  285.  
  286. extern volatile uint8_t gu8DCF_Status;
  287. extern volatile unsigned char gu8Rx_BitCnt;
  288. extern volatile uint16_t gu16aWeatherSeq[3];
  289. extern volatile uint64_t gu64Weather;
  290. extern volatile uint8_t gu8aWeatherData[5];
  291.  
  292. extern volatile uint16_t gu16Pulsweite;
  293. extern volatile uint32_t gu32DCF_msTimerSync;
  294.  
  295. extern volatile unsigned char ss;   //Globale Variable für Sekunden
  296. extern volatile unsigned char mm;   //Globale Variable für Minuten
  297. extern volatile unsigned char hh;   //Globale Variable für Stunden
  298. extern volatile unsigned char day;  //Globale Variable für den Tag
  299. extern volatile unsigned char mon;  //Globale Variable für den Monat
  300. extern volatile unsigned int year;  //Globale Variable für den Jahr
  301.  
  302. extern void Start_Clock(void); //Startet die DCF77 Uhr
  303. extern void Plip(uint8_t u8ZZ);
  304. #endif //_CLOCK_H
  305.  
  306. =============================================================
  307. C_SOUCRE
  308. =============================================================
  309.  
  310.  
  311. /*#######################################################################################
  312. 20.11.2019  Christof Ermer - Regensburg
  313.  
  314. https://gist.github.com/kronoc/c669eb8cceece1ea7f7ce3f964c511ee
  315.  
  316.  
  317. AVR AT328 DCF77 Clock
  318. DCF 77 Clock org. by Ulrich Radig,
  319. Sehr stark Modifiziert bei Christof Ermer - Regensburg
  320. Gänzlich andere Timerverwendung, UNION Typedef für die Daten etc..
  321. IDEE:
  322. https://www.ulrichradig.de/home/index.php/avr/dcf77_uhr
  323. https://www.ulrichradig.de/home/index.php/news/59/86/Bei-Radig-Hard-Software-01.08.2019
  324. Copyright (C) 2005 Ulrich Radig
  325.  
  326. http://www.gjlay.de/software/dcf77/konzept.html
  327. http://www.netzmafia.de/skripten/hardware/RasPi/Projekt-DCF77/
  328. https://www.mikrocontroller.net/articles/DCF77_Wetterinformationen
  329.     https://dcf77logs.de/wetter
  330.     http://www.fact4ward.com/blog/meteotime/
  331.     http://arduino-projects4u.com/pdf/DB%20W-Protokoll-V%201.pdf   
  332.     https://www.mikrocontroller.net/topic/61886#650725
  333.    
  334.    
  335.  
  336. https://xdec.de/msp430-dcf77-empfang-und-auswertung/
  337. https://www.mikrocontroller.net/topic/97295
  338. https://www.arduinoclub.de/2013/11/15/dcf77-dcf1-arduino-pollin/
  339.     Hier für sketch
  340. https://www.issb.de/mw/index.php/Test_elektronischer_Funkuhren-Module_(DCF77)_am_Mikroconcroller
  341. https://www.arduinoclub.de/2013/11/15/dcf77-dcf1-arduino-pollin/
  342. https://www.fingers-welt.de/phpBB/viewtopic.php?f=14&t=8161
  343. https://pic-projekte.de/blog/dcf77/
  344.  
  345. PON MUSS !!!! 1 SEKUND EHIGH, DANN LOW WERDEN. ALSO DOCH!
  346.  
  347. ACHTUNG
  348. Pollin Pinbelegung ist falsch in einem der gefundnen  Dokus. Data udn PON vertausch. Pon liegt aussen.
  349. PON (v+3.3V) 10µF an 10K gegen MasseIntegrator
  350. Richtig =
  351. AUSSENliegend =PON =
  352. TCO
  353. GND  = GND
  354. Etwas nach Innen VCC = 3.3V MAX
  355.  
  356.  
  357. AVR DCF77 Clock
  358. https://www.ulrichradig.de/home/index.php/avr/dcf77_uhr
  359. https://www.ulrichradig.de/home/index.php/news/59/86/Bei-Radig-Hard-Software-01.08.2019
  360. Copyright (C) 2005 Ulrich Radig
  361.  
  362.  
  363.  
  364. https://www.mikrocontroller.net/topic/97295
  365. https://www.arduinoclub.de/2013/11/15/dcf77-dcf1-arduino-pollin/
  366. http://www.netzmafia.de/skripten/hardware/RasPi/Projekt-DCF77/
  367. Hier für sketch
  368. https://www.issb.de/mw/index.php/Test_elektronischer_Funkuhren-Module_(DCF77)_am_Mikroconcroller
  369. https://www.arduinoclub.de/2013/11/15/dcf77-dcf1-arduino-pollin/
  370. https://www.fingers-welt.de/phpBB/viewtopic.php?f=14&t=8161
  371.  
  372.  
  373. https://pic-projekte.de/blog/dcf77/
  374. https://xdec.de/msp430-dcf77-empfang-und-auswertung/
  375.  
  376.  
  377. PON MUSS !!!! 1 SEKUNDE HIGH, DANN LOW WERDEN. ALSO DOCH!
  378.  
  379. ACHTUNG
  380. pollin Pinbelegung ist falscch
  381.  
  382. Richtig =
  383. AUSSENliegend =PON = GND  Feyst auf GROUND
  384. TCO
  385. GND  = GND
  386. Etwas nach Innen VCC = 3.3V MAX
  387.  
  388.  
  389. USES TIMER1  fuer 1 Sekundne Interrrupt  
  390. Das ist zu teuer
  391. T= mit OCR1A = 250 ist ebenfalls sehr genau
  392. T/256-. OCR 250 = 250
  393.  
  394. USED INTererupt = INT_1
  395.  
  396. T1= 15625 Hz
  397. aber durch PReload von 65535-- (F_CPU / 1024)
  398. TCNT1 = 65535U - (F_CPU / 1024)
  399. //65535U - 15625 =
  400. Zähle von 49910  auf 65536 = 15625  bei 15625Hz = 1 Sekunde !!
  401.  
  402. ALSO letzlich genau eine Sekunde!!
  403.  
  404.  
  405. Google
  406. DCF77 PSeudozufallszahl
  407. Es steck in jedem Bit noch eine FM 256 Bit Info
  408. Damit ist die Zeit NOCH sehr viel genauer
  409. MIt EXOR eine PLL Vergleich REFERENZ- Empfangsphase um Phase der Referenz nachzuziehen, sonst Schwebung.
  410. Pahsenvoreiluing testen welche vor, oder nachgeht, via Interrrupt auf XOR
  411. https://www.meinberg.de/german/info/dcf77.htm
  412.  
  413. if X<9 ? :     
  414. */
  415.  
  416. /*
  417. #include <avr/io.h>
  418. #include <avr/interrupt.h>
  419. */
  420. #include "main.h"
  421. //#include "FunkclockNew.h"
  422.  
  423. volatile uint32_t gu32DCF_msFreeRuner=0;
  424. volatile uint32_t gu32DCF_msTimerSync=0;
  425.  
  426. volatile uint16_t gu16Pulsweite=0;
  427. volatile unsigned char gu8Rx_BitCnt = 0;
  428.  
  429. volatile ST_DCF_FLAGS_TYPE gstDCF_Flags;
  430. volatile DCF77_UNION_T gstunDCF77_Bits; // union Struct
  431.  
  432. volatile uint16_t gu16aWeatherSeq[3];
  433. volatile uint64_t gu64Weather=0;
  434. volatile uint8_t gu8aWeatherData[5];
  435.  
  436. volatile uint8_t gu8DCF_Status = 0;
  437. volatile uint32_t gu32MS_NOW =0;
  438.  
  439. //Bitzähler für RX Bit
  440. //64 Bit für DCF77 benötigt werden 59 Bits
  441.  
  442. /*
  443. gstunDCF77_Bits.bitRx_Buffer
  444. gstunDCF77_Bits.u64DCF_RxBuffer
  445. */
  446.  
  447. //Die Uhrzeit seht in folgenden Variablen
  448. volatile unsigned char ss   = 0;   //Globale Variable für die Sekunden
  449. volatile unsigned char mm   = 0;   //Globale Variable für die Minuten
  450. volatile unsigned char hh   = 0;   //Globale Variable für die Stunden
  451. volatile unsigned char day   = 0;   //Globale Variable für den Tag
  452. volatile unsigned char mon   = 0;   //Globale Variable für den Monat
  453. volatile unsigned int year   = 0;   //Globale Variable für das Jahr
  454.  
  455.  
  456. /*  **** WETTER *****
  457.  
  458. https://www.mikrocontroller.net/articles/DCF77_Wetterinformationen
  459.  
  460. 3* 14 BITS = 42 Bit
  461. DCF Protokoll ist hinreichend bekannt.
  462. Es gibt 14 Datenbits, in 3 Minuten wird ein Datensatz übertragen (= 42 bit)
  463. 90 Regionen, 4 mal täglich Informationen, jeweils 3 Minuten: ergibt 1080 Sendeminuten pro Tag (1440 Minuten). Rest 360 (5040 bit).
  464. 4 mal täglich werden Infos zu einer Zone gesendet:
  465.  
  466. * 22:00 - 03:59    Aktueller / kommender Tag (TODAY im Display)
  467. * 04:00 - 09:59    Folgender Tag (DAY 1 im Display)
  468. * 10:00 - 15:59    Darauffolgender Tag (DAY 2 im Display)
  469. * 16:00 - 18:59    Darauffolgender Tag (DAY 3 im Display)
  470. * 19:00 - 21:59    30 Zusatzregionen mit 2-Tages-Prognose
  471. http://www.wetterstationen.info/mete-on-1.php
  472.  
  473. Die Daten sind verschlüsselt
  474. Die entschlüsselten Daten können dekodiert werden
  475. http://www.hkw-elektronik.de/pdf/DB%20W-Protokoll-V%201.pdf
  476.  
  477. */
  478.  
  479. //Hilfs Sekunden Counter
  480. volatile unsigned int gu16H_ss = 0;
  481. //Hilfs Variable für Stundenwechsel
  482. volatile unsigned int gu16H_hh = 0;
  483.  
  484. // PRPTO
  485. void Add_one_Second (void);
  486. void Plip(uint8_t u8ZZ);
  487. /*
  488. //############################################################################
  489. void Try_Interrupt_Debounce(void)   //for bad signalquality
  490.     {
  491. static uint32_t u3DCF_IntTime;  //Merk Dir die Zeit
  492.         if( gstDCF_Flag & DCF_EVENT  )
  493.         {
  494.         DCF77_INT_DISABLE();    //lösche alle ints, weil störungen
  495.         INT_FLAG_REG |= (1 << INTF1); // lösche flag, Siehe pdf
  496.         gstDCF_Flag &= INTSTATUS_CLR_INT_MASK;
  497.         gstDCF_Flag |= DCF_DISABLED;
  498.         u3DCF_IntTime = gu32_Ticks;
  499.         };
  500.    
  501.     if( gstDCF_Flag & DCF_DISABLED )
  502.         {
  503.         if( gu32_Ticks >=  (u3DCF_IntTime + DELAY_INT_WIEDER_ON) )
  504.             {
  505.             //244 Ticks/Sekunde ind 24 pro 100MS
  506.             //Weil da sSignal so schlecht ist.... einfach unerwünschtes aussprren
  507.             INT_FLAG_REG = (1<< INTF1); // lösche alle INT Ereignisse // Siehe pdf
  508.             gstDCF_Flag &= INTSTATUS_CLR_INT_MASK;
  509.             DCF77_INT_ENABLE(); // INT Wieder einschalten nach eine rguten Zeit
  510.             };
  511.         };
  512.     };
  513. */
  514. //PROTO
  515. // ********************************
  516. void DCF_Zyklus_59_Fertig( void );
  517. // ********************************
  518.  
  519. // ********************
  520. void ResetDCFBuf(void)
  521. // ********************
  522. {
  523. gu8Rx_BitCnt = 0;
  524. gstunDCF77_Bits.u64DCF_RxBuffer = 0;
  525. gstDCF_Flags.parity_err = 0;
  526. gstDCF_Flags.parity_P1 = 0;
  527. gstDCF_Flags.parity_P2 = 0;
  528. gstDCF_Flags.parity_P3 = 0;
  529. };
  530.  
  531.  
  532. //############################################################################
  533. //Diese Routine startet und inizialisiert den Timer
  534. void Start_Clock(void)
  535. //############################################################################
  536. {
  537. DCF_INTX_DDRX_INIT();
  538. INT_X_RISING_EDGE();
  539. CLEAR_INTX_FLAG();
  540. DCF77_INT_ENABLE();
  541. //PON richtig bedienen, beim Pollin DCF:
  542. //Integrator (V+)10µF-C und 10K gegen Masse. = H.L
  543.  
  544. ResetDCFBuf();
  545.  
  546. ss   = 0;   //Globale Variable für die Sekunden
  547. mm   = 0;   //Globale Variable für die Minuten
  548. hh   = 0;   //Globale Variable für die Stunden
  549. day   = 0;   //Globale Variable für den Tag
  550. mon   = 0;   //Globale Variable für den Monat
  551. year   = 0;   //Globale Variable für das Jahr
  552.  
  553. gstDCF_Flags.parity_err = 0;
  554. gstDCF_Flags.parity_P1 = 0;
  555. gstDCF_Flags.parity_P2 = 0;
  556. gstDCF_Flags.parity_P3 = 0;
  557. gstDCF_Flags.dcf_sync = 0;
  558.  
  559. //Interrupt DCF77 einschalten auf ansteigende Flanke
  560. // NUTZE TIMER 2 für 1000 Hz Interrupt = ms Auflösung
  561. TCNT2 = 0;
  562. TCCR2A=(11<< WGM21);  //CTC
  563. TIMSK2 = (1 << OCIE2A); //OIE2
  564. TIFR2 = (1 << OCF2A); // Flag weg mit "="
  565. OCR2A =250;
  566. //Setzen des Prescaler auf 64
  567. TCCR2B = (1<< CS22); // = 1000/sec
  568. gu32DCF_msFreeRuner = 0;
  569. gu32DCF_msTimerSync = 0;
  570. };
  571.  
  572.  
  573. // ############################################################################
  574. //Overflow Interrupt wird ausgelöst bei 59Sekunde oder fehlenden DCF77 Signal
  575. ISR(TIMER2_COMPA_vect) //TIMER2_OVF_vect
  576. //############################################################################
  577. {  
  578. cli(); // Damit kein anderer Int dazuischenpfuzscht
  579. gu32DCF_msFreeRuner++;  //no reset
  580. gu32DCF_msTimerSync++;  //perioidisch 0 gestellt bis 59 fertig, dann 1000
  581. sei();
  582.  
  583. if( gu32DCF_msTimerSync >= 1000 ) //Sekunde
  584.     {
  585.     gu32DCF_msTimerSync = 0;
  586.     DCF_Zyklus_59_Fertig();
  587.     };
  588.  
  589. if( (gu32DCF_msFreeRuner - gu32MS_NOW) > DCF_NOSIGNAL_TIMEOUT )
  590.     {
  591.     gstDCF_Flags.dcf_NoSignal = 1;
  592.     }
  593. else
  594.     {
  595.     gstDCF_Flags.dcf_NoSignal = 0;
  596.     }; 
  597. };
  598.    
  599.  
  600. // *****************************
  601. void DCF_Zyklus_59_Fertig(void)
  602. // *****************************
  603. {
  604. //struct DCF77_Bits * gstunDCF77_Bits.bitRx_Buffer = (struct DCF77_Bits*)(char*)&gstunDCF77_Bits.u64DCF_RxBuffer;  
  605. //wurden alle 59 Bits empfangen und sind die Paritys richtig?
  606.  
  607. if(gu8Rx_BitCnt > 59) {Start_Clock();};
  608.  
  609. if( (gu8Rx_BitCnt == 59)                                         &&  //==
  610.     (gstDCF_Flags.parity_P1 == gstunDCF77_Bits.bitRx_Buffer.P1) &&
  611.     (gstDCF_Flags.parity_P2 == gstunDCF77_Bits.bitRx_Buffer.P2) &&
  612.     (gstDCF_Flags.parity_P3 == gstunDCF77_Bits.bitRx_Buffer.P3)
  613.  
  614. )
  615.     //Alle 59Bits empfangen stellen der Uhr nach DCF77 Buffer
  616.     {  
  617.     //Berechnung der Minuten BCD to HEX
  618.     mm = gstunDCF77_Bits.bitRx_Buffer.Min-((gstunDCF77_Bits.bitRx_Buffer.Min/16)*6);   
  619.     if(mm != 0)
  620.         {mm--;}
  621.     else
  622.         {mm = 59; gu16H_hh = 1;};
  623.    
  624.     //Berechnung der Stunden BCD to HEX
  625.     hh = gstunDCF77_Bits.bitRx_Buffer.Hour-((gstunDCF77_Bits.bitRx_Buffer.Hour/16)*6);
  626.     if (gu16H_hh) {hh--; gu16H_hh = 0;};
  627.  
  628.     //Berechnung des Tages BCD to HEX
  629.     day= gstunDCF77_Bits.bitRx_Buffer.Day-((gstunDCF77_Bits.bitRx_Buffer.Day/16)*6);
  630.     //Berechnung des Monats BCD to HEX
  631.     mon= gstunDCF77_Bits.bitRx_Buffer.Month-((gstunDCF77_Bits.bitRx_Buffer.Month/16)*6);
  632.     //Berechnung des Jahres BCD to HEX
  633.     year= 2000 + gstunDCF77_Bits.bitRx_Buffer.Year-((gstunDCF77_Bits.bitRx_Buffer.Year/16)*6);
  634.     //Sekunden werden auf 0 zurückgesetzt
  635.     ss = 59;
  636.     gstDCF_Flags.dcf_sync = 1; 
  637.     gu8DCF_Status |= DCF_SYNC;
  638.     gstDCF_Flags.dcf_BeepLong = 1; 
  639.  
  640.     /*
  641.     WEATHER
  642.     MIN =? Modulo 3
  643.  
  644.     DMY:27-11-2019 Time: 09:34:58  Sync:1  Rx:0
  645.     DCFstat:10111010       RxCnt:59
  646.     DCF_FLAGS_10111011
  647.     DCF:0000010001100110001011100111000100100110101101000100100001110000
  648.    
  649. Weather_1: 0010110000010110     Weather_2: 0011110111010101     Weather_3: 0001101010010001
  650.         Weather_64:0000000000000000000000000000000001000111110111010101101100001011  
  651.                                             110101001000111110111010101101100001011
  652.  
  653. Weather_5Byte:  W5: 00000000    W4: 01000111    W3: 11011101    W2: 01011011    W1: 00001011
  654.     */
  655.    
  656.     gu16aWeatherSeq[ mm % 3 ]  = gstunDCF77_Bits.bitRx_Buffer.Weather; 
  657.     //14 Bit / wort
  658.     gu64Weather = ((gu16aWeatherSeq[0] & 0x7E)  >> 1); // 1.2 6 bit, Blende 0 & 7 aus
  659.     gu64Weather |= ((gu16aWeatherSeq[0] & 0x3F00UL) >> 2); //= 12 BIT  2. 8 bit Rücke nach
  660.     gu64Weather |= ((gu16aWeatherSeq[1] & 0x3FFFUL) << 12); //
  661.     gu64Weather |= ((gu16aWeatherSeq[2] & 0x3FFFULL) << 26 );
  662.    
  663.    
  664.     gu8aWeatherData[0]= (gu64Weather & 0xFF);
  665.     gu8aWeatherData[1]= ( (gu64Weather >> 8) & 0xFF);
  666.     gu8aWeatherData[2]= ( (gu64Weather >> 16) & 0xFF);
  667.     gu8aWeatherData[3]= ( (gu64Weather >> 24) & 0xFF);
  668.     gu8aWeatherData[4]= ( (gu64Weather >> 32) & 0xFF);
  669.     // STIMMMTZ NICHT  14 BIT Runterbrechen auf 5*14=50 Bit
  670. }
  671. else
  672.     {
  673.     Add_one_Second();
  674.     gstDCF_Flags.dcf_sync = 0;
  675.     };
  676. //CLEAR ALL
  677. //zurücksetzen des RX Bit Counters
  678. ResetDCFBuf();
  679. };
  680.  
  681.  
  682.  
  683. //############################################################################
  684. //DCF77 Modul empfängt Träger
  685. ISR (DCF77_INT_VECT)  //INT_X Intererrupt
  686. //############################################################################
  687. {
  688. unsigned int uiPulseWide;
  689. //DCF77_INT_DISABLE();
  690.    //Auswertung der Pulseweite
  691. if(  (INTX_EDGE_CTRL_REG  & INT_X_EDGE_MASK)  ==  INT_X_RISING_EDGE_BITS)
  692.     {
  693.  
  694. gu8DCF_Status &= ~DCF_FALLING_INT;
  695. gu8DCF_Status |= DCF_RISING_INT;
  696.  
  697.     gstDCF_Flags.dcf_NoSignal = 0;
  698.     gstDCF_Flags.dcf_rx ^= 1;
  699.     //Sekunden Hilfs Counter berechnen
  700.     gu16H_ss += (gu32DCF_msTimerSync % 1000);
  701.     cli();  
  702.     gu32DCF_msTimerSync = 0; // Zurücksetzen  Aufruftimer
  703.     gu32MS_NOW = gu32DCF_msFreeRuner;  // STARTzeit MERKEN steigende Flanke    
  704.     sei(); // //Zurücksetzen des Timers
  705.    
  706.     ///ist eine Secunde verstrichen //
  707.     if (gu16H_ss > 900) //900=ms 90% von 1Sekunde
  708.         {
  709.         //Addiere +1 zu Sekunden
  710.         Add_one_Second();
  711.         gu16H_ss = 0;
  712. gu8DCF_Status |= DCF_INT_SEC;      
  713.         //Zurücksetzen des Hilfs Counters
  714.         }
  715. //Nächster Interrupt wird ausgelöst bei abfallender Flanke
  716.     CLEAR_INTX_FLAG();
  717.     INT_X_FALLING_EDGE();
  718.     }
  719. else  //Fallend EDGE
  720.     {  
  721. gu8DCF_Status &= ~DCF_RISING_INT;
  722. gu8DCF_Status |= DCF_FALLING_INT;
  723.   //Auslesen der Pulsweite von ansteigender Flanke zu abfallender Flanke
  724.     cli();  
  725.     uiPulseWide = gu32DCF_msFreeRuner - gu32MS_NOW; // Pulslänge
  726.     gu32DCF_msTimerSync = 0; // Zurücksetzen  Aufruftimer
  727.     sei();
  728. // *********************   
  729. gu16Pulsweite  = uiPulseWide;   //NUR UM ES ANZEIGEN ZU KÖNNEN
  730. // *********************   
  731.  
  732.     if( uiPulseWide > DEBOUNCE_TO_SHORT_MS ) // <90ms
  733.         {
  734.         //Sekunden Hilfs Counter berechnen
  735.         gu16H_ss += uiPulseWide;
  736.         //Parity speichern
  737.         //beginn von Bereich P1/P2/P3
  738.         if(gu8Rx_BitCnt ==  21 || gu8Rx_BitCnt ==  29 || gu8Rx_BitCnt ==  36)
  739.             {
  740.             gstDCF_Flags.parity_err = 0;
  741.             };
  742.         //Speichern von P1
  743.         if (gu8Rx_BitCnt ==  28) {gstDCF_Flags.parity_P1 = gstDCF_Flags.parity_err;};
  744.         //Speichern von P2
  745.         if (gu8Rx_BitCnt ==  35) {gstDCF_Flags.parity_P2 = gstDCF_Flags.parity_err;};
  746.         //Speichern von P3
  747.         if (gu8Rx_BitCnt ==  58) {gstDCF_Flags.parity_P3 = gstDCF_Flags.parity_err;};
  748.            
  749.         //Überprüfen ob eine 0 oder eine 1 empfangen wurde
  750.         //0 = 100ms
  751.         //1 = 200ms
  752.         //Abfrage größer als 150ms (15% von 1Sekund also 150ms)  
  753.         if( uiPulseWide > 150 )
  754.             {
  755.             //Schreiben einer 1 im gu64DCF_gstunDCF77_Bits.bitRx_Buffer an der Bitstelle gu8Rx_BitCnt
  756.             gstunDCF77_Bits.u64DCF_RxBuffer |= (1ULL << gu8Rx_BitCnt);         
  757.             //Toggel Hilfs Parity          
  758. // ?????????????????????????????????????????????????????????????????????????           
  759.             gstDCF_Flags.parity_err ^= 1;      
  760. gu8DCF_Status|= DCF_DETECT_H;
  761. gu8DCF_Status &= ~DCF_DETECT_L;
  762.             }
  763.         else  // 0
  764.             {
  765. //gu8ProgStatusFlags |= BEEP100MS;
  766.             //gstunDCF77_Bits.u64DCF_RxBuffer &= ~(1ULL << gu8Rx_BitCnt);
  767.             gu8DCF_Status |= DCF_DETECT_L;
  768.             gu8DCF_Status &= ~DCF_DETECT_H;
  769.             };
  770.         //RX Bit Counter wird um 1 incrementiert
  771.         gu8Rx_BitCnt++;
  772.         //Nächster Interrupt wird ausgelöst bei ansteigender Flanke
  773.          //Nächster Interrupt wird ausgelöst bei ansteigender Flanke
  774.         CLEAR_INTX_FLAG() ;
  775.         INT_X_RISING_EDGE();   
  776.         }; // to short Debounce    
  777.     };
  778. };
  779.  
  780.  
  781.  
  782. //############################################################################
  783. //Addiert 1 Sekunde
  784. void Add_one_Second(void)
  785. //############################################################################
  786. {
  787. ss++;//Addiere +1 zu Sekunden
  788. if (ss == 60)
  789.     {
  790.     ss = 0;
  791.     mm++;//Addiere +1 zu Minuten
  792.     if (mm == 60)
  793.         {
  794.         mm = 0;
  795.         hh++;//Addiere +1 zu Stunden
  796.         if (hh == 24)
  797.             {
  798.             hh = 0;
  799.             };
  800.         }
  801.     }
  802. gstDCF_Flags.dcf_SecPuls = 1;
  803. };
  804.  
  805.  
  806. // *************************************
  807. void Plip(uint8_t u8ZZ)
  808. // *************************************
  809. {
  810. BEEP_INIT(); //WEGEN SUMMER
  811. if(gu8ProgStatusFlags & BEEP_TON_ON)
  812.     {
  813.     DCF_BEEP_PORT |= DCF_BEEP_BIT;
  814.     wdt_reset();    //WATCHDOG!
  815.     _delay_ms( u8ZZ );
  816.     wdt_reset();    //WATCHDOG!
  817.     DCF_BEEP_PORT &= ~DCF_BEEP_BIT;
  818.     };
  819. };
  820.  
  821.  
  822. ============================================================
  823. MAIN HEADER
  824. =================================
  825.  
  826.  
  827. // Versoon 20.11.2019
  828.  
  829. #ifndef MAIN_HEADER  //Prevents multiple includes
  830.     #define MAIN_HEADER
  831.    
  832. #include <stdio.h>
  833. #include <avr/sfr_defs.h>
  834. #include <stdlib.h>
  835. #include <avr\io.h>
  836. #include <util\delay.h>
  837. #include <ctype.h>
  838. #include <avr/wdt.h>
  839. #include <avr\interrupt.h>
  840. #include <string.h>
  841. #include <avr/pgmspace.h>
  842. #include <math.h>
  843. #include "PCF8574.h"
  844. #include "max7219.h"
  845. #include "uart328.h"
  846. #include "i2cmaster.h"
  847. #include "i2clcd.h"
  848. #include "debug.h"
  849. #include "ServiceFunc.h"
  850. #include "Befehle.h"
  851. #include "max7219.h"
  852. #include "LT1057_DAC.h"
  853. //#include "Funkclock.h"
  854. #include "FunkclockNew.h"
  855.  
  856. //#define LED1_BLINK (1<<PB5)   //LED an BIT 0
  857.  
  858. #define PCF8574_LED_AR  0x27  //Alle Jumper Linkszum chip = V+
  859.  
  860. // in Befehle.h: #define UART_BAUD_RATE 115200UL    //UART_BAUD_SELECT_DOUBLE_SPEED
  861. // Hardwareassignment
  862. //PORTD TX/RX ERST MAL FÜR  FLAGS
  863. #define PD0_RX_BIT  0x01    //PIN2
  864. #define PD1_TX_BIT  0x02    //PIN3
  865.  
  866. //RUNDUNG
  867. //16MHZ /72000 -> 222.2222222... = oCR0A=222
  868. // 16000000 / 244 = ~72072
  869. //#define TICK_1000MS   72072UL
  870. #define TICK_1000MS 250U
  871. //#define TICK_100MS    7207U
  872. #define TICK_DAC_N250   10
  873.  
  874. #define STATUS_TICK_EVENT   0x01
  875. #define STATUS_DAC_EVENT    0x02
  876. #define HELP_SEC_GR_900     0x04
  877. #define PLIP_SHORT          0x10
  878. #define BEEP100MS           0x20
  879. #define BEEP200MS           0x40
  880. #define BEEP_TON_ON         0x80
  881. //gu8ProgStatusFlags
  882.  
  883.  
  884. //INTERNE LED
  885. #define INTLED_NR       5
  886. #define INTLED_PORT     PORTB
  887. #define INTLED_DDR      DDRB
  888. #define INTLED_INIT()   (INTLED_DDR |= (1<<INTLED_NR))
  889. #define TOGGLE_INTLED() (INTLED_PORT ^= (1<<INTLED_NR))
  890. #define SET_INTLED()    (INTLED_PORT |= (1<<INTLED_NR))
  891. #define CLR_INTLED()    (INTLED_PORT &= ~(1<<INTLED_NR))
  892.  
  893.  
  894. extern volatile uint32_t gu32_Ticks;//  T2 timeCounter
  895. extern volatile uint8_t gu32DAC_Tick;
  896.  
  897. extern volatile uint8_t gu8ProgModeFlag;
  898. extern volatile uint8_t gu8ProgStatusFlags;
  899. extern volatile float gfSollFRQ; //Hz
  900.  
  901. #endif  //MAIN_HEADER
  902.  
  903.  
  904. =============================================
  905. Main C
  906. =======================================
  907.  
  908.  
  909. //------------------------------------------------------------------------------
  910. // Programmed by Christof Ermer
  911. //------------------------------------------------------------------------------
  912. #define DATUM       "Version 19.11.2019"
  913. #define SOFTWARE    "DCF Pollin Receiver-V1.3"
  914. #define HARDWARE    "Arduino-UNO ATMega328"
  915. #define AUTOR       "Christof Ermer"
  916. #define IHAVENOBRAIN    "I have no brain." 
  917. #define USEYOURS        " Use your own!"
  918.  
  919. #include "main.h"
  920.  
  921. // GLOBALE VARIABLEN
  922. volatile uint32_t gu32_Ticks;    //  T2 TimerCounter
  923. volatile uint8_t gu8ProgStatusFlags;
  924. volatile uint8_t gu32DAC_Tick = TICK_DAC_N250;
  925. volatile float gfSollFRQ = 77500.0; //Hz
  926.  
  927. // ***************************
  928. ISR( TIMER0_COMPA_vect )  //250 Hz
  929. /// ***************************
  930. {
  931. gu32_Ticks++;
  932. UART_RX_Check();
  933.  
  934. if( !(gu32_Ticks % TICK_1000MS) )
  935.     {
  936.     gu8ProgStatusFlags |= STATUS_TICK_EVENT;
  937.     };
  938.  
  939. if( !(gu32_Ticks % gu32DAC_Tick) )
  940.     {
  941.     gu8ProgStatusFlags |= STATUS_DAC_EVENT;
  942.     };
  943.  
  944. gu8ProgStatusFlags |= STATUS_DAC_EVENT;
  945. };
  946.  
  947.  
  948. // *************
  949. int main(void)
  950. // *************
  951. {
  952. uint8_t u8NN=0;
  953. uint16_t u16DAC;
  954. uint16_t u16DAC_Cnt =0;
  955. uint32_t u32CPULoops=0;
  956.  
  957. INTLED_INIT();
  958.  
  959. wdt_reset();  
  960. wdt_enable(WDTO_1S); //500mS Totmannknopf
  961.  
  962.  
  963. Init_UART( UART_BAUD_RATE );  //Befehle.c
  964. sei();
  965.  
  966.  
  967.  
  968. // TWI initialisieren
  969. i2c_init();
  970. /*
  971. MAX7219_Init();
  972. MAX7219_Clear();
  973. MAX7219_Write(1, 0x5A);
  974. */
  975.  
  976. // LCD initialisieren
  977. lcd_init();
  978. // LCD-Anzeige loeschen
  979. lcd_command(LCD_CLEAR);
  980. // Hintergrundbeleuchtung an
  981. lcd_backlight(ON);
  982.  
  983. PCF8574_Init(LCD_PCF8574_ADR_PREFIX);  //LCD
  984. PCF8574_Init(PORTEXPANDER_PCF8574_ADR_PREFIX);  //LEDLEISTE
  985.  
  986. // Text auf LCD ausgeben
  987. // MIT RAM , als falsch
  988. strcpy_P( gcaStr, PSTR("* I2C LCD *") );
  989. lcd_printlc(1,1,(unsigned char *)gcaStr);
  990. strcpy_P( gcaStr, PSTR("*Christof Ermer*"));
  991. lcd_printlc(2,1,(unsigned char *)gcaStr);
  992.  
  993. CRLF();uart_puts_p( PSTR( DATUM ) );
  994. CRLF();uart_puts_p( PSTR( SOFTWARE ) );
  995. CRLF();uart_puts_p( PSTR( HARDWARE ) );
  996. CRLF();uart_puts_p( PSTR( AUTOR ) );
  997.  
  998. //MAX7219_Clear();
  999.  
  1000. // TickCounter Starten
  1001. TCNT0 = 0;
  1002. OCR0A = 250;
  1003. TCCR0A = (1<< WGM01) ;  //CTC
  1004. TIMSK0 = (1<< OCIE0A);  //INT
  1005. //TIMSK0 = (1<< TOIE0); //Aktiviert Int0 OVL Interrupt
  1006. TCCR0B = (1<< CS02); //256
  1007. sei();
  1008.  
  1009. #ifdef USE_T2_AUToPRESCALER
  1010. TCNT2=0;
  1011. DDRB |= (1<<PB3);  
  1012. //OCRx =  Quarz / Vorteiler / gewünschte Frequenz
  1013. SelectBestPreScaler_T2( gfSollFRQ );
  1014. TCCR2A= (1<< COM2A0) | (1<< WGM21); //Toogle OC2A  FEHLER IN PDF
  1015. sei();
  1016. #endif
  1017.  
  1018. #ifdef USE_T1_AUToPRESCALER
  1019. TCNT1=0;
  1020. DDRB |= (1<<PB1);  
  1021. //OCRx =  Quarz / Vorteiler / gewünschte Frequenz
  1022. SelectBestPreScaler_T1( gfSollFRQ );
  1023. TCCR1A= (1<< COM1A0);  // Toogle OC1A
  1024. sei();
  1025. #endif
  1026.  
  1027. Start_Clock();
  1028.  
  1029. wdt_reset();    //WATCHDOG!
  1030. uart_puts_p( PSTR("\r\nDCF77 Clock org.by Ulrich Radig, modification by. Christof Ermer - Regensburg\r\n") );
  1031. wdt_reset();    //WATCHDOG!
  1032.  
  1033. SET_INTLED();
  1034. Plip( BEEP_LONG_MS );
  1035. for(;;)
  1036.     {
  1037.     sei();
  1038.     wdt_reset();    //WATCHDOG!
  1039.     u32CPULoops++;
  1040.  
  1041.     i2c_start_wait(  PORTEXPANDER_PCF8574_ADR_PREFIX + I2C_WRITE );
  1042.     i2c_write( gu8DCF_Status ); // If( 2c_write(   ........
  1043.     i2c_stop();
  1044.  
  1045.     if( gu8ProgStatusFlags & STATUS_DAC_EVENT )
  1046.         {
  1047.         gu8ProgStatusFlags &= ~STATUS_DAC_EVENT;
  1048.         u16DAC = 2047 + 2046 *  sin ( 2* M_PI * (u16DAC_Cnt/2048.0) );
  1049.         u16DAC_Cnt++;
  1050.         u16DAC_Cnt %= 2048;
  1051.         LT2157(u16DAC);    
  1052.         };
  1053.  
  1054. // --------------------------------------------------------------------
  1055.     if( gstDCF_Flags.dcf_NoSignal )
  1056.         {
  1057.         gu8DCF_Status ^= 0xFF;    // bkinke wie blöd  
  1058.         };
  1059.    
  1060.  
  1061.     if( gstDCF_Flags.dcf_SecPuls ) 
  1062.         {
  1063.         gstDCF_Flags.dcf_SecPuls = 0;  
  1064.         TOGGLE_INTLED(); // 1,0HZ  
  1065.         Plip( BEEP_KNACKS_MS );    
  1066.         };
  1067.  
  1068.     if( gstDCF_Flags.dcf_Plip )
  1069.         {
  1070.         gstDCF_Flags.dcf_Plip = 0; 
  1071.         Plip( BEEP_KNACKS_MS );
  1072.         TOGGLE_INTLED(); // 1,0HZ  
  1073.         };
  1074.  
  1075.     if( gstDCF_Flags.dcf_Beep )
  1076.         {
  1077.         gstDCF_Flags.dcf_Beep= 0;  
  1078.         Plip( BEEP_SHORT_MS); //Piepser oder so
  1079.         //BEEP_PAUSE
  1080.         };
  1081.     if( gstDCF_Flags.dcf_BeepLong )
  1082.         {
  1083.         gstDCF_Flags.dcf_BeepLong = 0; 
  1084.         Plip( BEEP_LONG_MS ); //Piepser oder so
  1085.         };
  1086.  
  1087.     if( gu8DCF_Status & DCF_Sec_Puls )
  1088.         {      
  1089.         gu8DCF_Status &= ~DCF_Sec_Puls;
  1090.         };
  1091.  
  1092. // --------------------------------------------------------------------        
  1093.        
  1094. //Toggle_Bit(1);
  1095.     if( gu8ProgStatusFlags & STATUS_TICK_EVENT )
  1096.         {
  1097.         gu8ProgStatusFlags &= ~STATUS_TICK_EVENT;
  1098.         //TOGGLE_INTLED();
  1099.        
  1100.         if( gstDCF_Flags.dcf_NoSignal )
  1101.             {
  1102.             uart_puts_p( PSTR("\r\n\t ** NO DCF SIGNAL ***") );
  1103.             };
  1104.         CRLF();
  1105.         CRLF();    
  1106.         uart_puts_p( PSTR("MCU:") );
  1107.         ultoa( u32CPULoops, gcaNumStr, 10 );
  1108.         u32CPULoops=0;
  1109.         uart_puts( gcaNumStr );
  1110.                
  1111.         uart_puts_p( PSTR("\tFrq:") );
  1112.         FloatToNumStr(gfSollFRQ);
  1113.         uart_puts( gcaNumStr );        
  1114.        
  1115.         CRLF();    
  1116.         uart_puts_p( PSTR("gu16Pulsweite:") );
  1117.         ultoa( gu16Pulsweite, gcaNumStr, 10 );
  1118.         uart_puts( gcaNumStr );
  1119.  
  1120.         CRLF();    
  1121.         uart_puts_p( PSTR("gu32DCF_msTimerSync:") );
  1122.         ultoa( gu32DCF_msTimerSync, gcaNumStr, 10 );
  1123.         uart_puts( gcaNumStr );
  1124.        
  1125.         CRLF();
  1126.         sprintf(gcaStr, "\t DMY:%02d-%02d-%02d Time: %02d:%02d:%02d \tSync:%d \tRx:%d", //%i
  1127.             day,mon,year,hh,mm,ss, gstDCF_Flags.dcf_sync, gstDCF_Flags.dcf_rx);
  1128.         uart_puts( gcaStr );
  1129.        
  1130.        
  1131.         CRLF();
  1132.         uart_puts_p( PSTR("DCF:") );
  1133.         uart_puts( U64ToBin( gstunDCF77_Bits.u64DCF_RxBuffer ) );
  1134.  
  1135.         CRLF();
  1136.         uart_puts_p( PSTR("DCFstat:") );       
  1137.         uart_puts( ByteToBin( gu8DCF_Status ) );
  1138.                
  1139.         uart_puts_p( PSTR("\tRxCnt:") );
  1140.         uart_puts( ULongToNumStr( gu8Rx_BitCnt ) );
  1141.  
  1142.         CRLF();
  1143.         uart_puts_p( PSTR("DCF_FLAGS_") );
  1144.         u8NN  |= (gstDCF_Flags.parity_err << 0);
  1145.         u8NN  |= (gstDCF_Flags.parity_P1 << 1);
  1146.         u8NN  |= (gstDCF_Flags.parity_P2 << 2);
  1147.         u8NN  |= (gstDCF_Flags.parity_P3 << 3);
  1148.         u8NN  |= (gstDCF_Flags.dcf_rx << 4);
  1149.         u8NN  |= (gstDCF_Flags.dcf_sync << 5);
  1150.         u8NN  |= (gstDCF_Flags.dcf_NoSignal << 6);     
  1151.         u8NN  |= (gstDCF_Flags.dcf_SecPuls << 7);      
  1152.         uart_puts( ByteToBin( u8NN ) );
  1153.    
  1154.         CRLF();
  1155.         uart_puts_p( PSTR("Weather_1: ") );
  1156.         uart_puts( WordToBin( gu16aWeatherSeq[0] ) );
  1157.         uart_puts_p( PSTR("\tWeather_2: ") );
  1158.         uart_puts( WordToBin( gu16aWeatherSeq[1] ) );
  1159.         uart_puts_p( PSTR("\tWeather_3: ") );
  1160.         uart_puts( WordToBin( gu16aWeatherSeq[2] ) );
  1161.  
  1162.         CRLF();
  1163.         uart_puts_p( PSTR("\tWeather_64:") );
  1164.         uart_puts( U64ToBin( gu64Weather ) );
  1165.    
  1166.         CRLF();
  1167.         uart_puts_p( PSTR("Weather_5Byte: ") );
  1168.         uart_puts_p( PSTR("\tW5: ") );
  1169.         uart_puts( ByteToBin(gu8aWeatherData[4]) );
  1170.         uart_puts_p( PSTR("\tW4: ") );
  1171.         uart_puts( ByteToBin(gu8aWeatherData[3]) );
  1172.         uart_puts_p( PSTR("\tW3: ") );
  1173.         uart_puts( ByteToBin(gu8aWeatherData[2]) );
  1174.         uart_puts_p( PSTR("\tW2: ") );
  1175.         uart_puts( ByteToBin(gu8aWeatherData[1]) );
  1176.         uart_puts_p( PSTR("\tW1: ") );
  1177.         uart_puts( ByteToBin(gu8aWeatherData[0]) );
  1178.  
  1179.  
  1180. /// LCD **  LCD **  LCD **  LCD **  LCD **  LCD **  LCD **  LCD **  LCD **  LCD **
  1181.         lcd_command(LCD_CLEAR);    
  1182.         sprintf(gcaStr, "%02d:%02d:%02d",hh,mm,ss );
  1183.         strcat_P( gcaStr, PSTR(" ") );
  1184.         FloatToNumStr(gfSollFRQ);
  1185.         strcat( gcaStr, gcaNumStr);
  1186.         *(gcaStr+16) = 0;
  1187.         lcd_printlc(1, 1, (unsigned char *)gcaStr );
  1188.  
  1189.         //utoa(year,gcaNumStr,10);             
  1190.        
  1191.         sprintf(gcaStr, "%02d.%02d.%02d",day,mon,year);
  1192.        
  1193.         strcat_P( gcaStr, PSTR(" B") );    
  1194.        
  1195.         ultoa( gu8Rx_BitCnt, gcaNumStr, 10 );
  1196.         strcat( gcaStr, gcaNumStr);    
  1197.  
  1198.  
  1199.         strcat_P( gcaStr, PSTR(" S") );    
  1200.         ultoa( gstDCF_Flags.dcf_sync, gcaNumStr, 10 );
  1201.         strcat( gcaStr, gcaNumStr);    
  1202.         *(gcaStr+16)=0;
  1203.         lcd_printlc(2, 1, (unsigned char *)gcaStr);//lcd_printlc(2,1,(unsigned char *)gcaStr);
  1204.     /*
  1205.         strcat_P(gcaStr, PSTR(" S:") );
  1206.         ultoa( u16DAC, gcaNumStr, 10 );
  1207.         strcat( gcaStr, gcaNumStr);
  1208. */
  1209.         //strcpy_P( gcaStr, PSTR("* I2C LCD *") );
  1210.         }; //TICK
  1211.        
  1212.     if( gu8BefehleFlags & BEFEHLE_ORDER_FLAG )
  1213.         {
  1214.         CheckOrder();//gcaRxStr = accumulated str
  1215.         ResetRxBuff();
  1216.         };
  1217.     //CLR_INTLED();
  1218.     }; //for
  1219. }; // main
  1220.  
  1221. ====================================================================
  1222. ServiceFunc.c + HEADER
  1223. =================================
  1224. // HEADER
  1225.  
  1226. #ifndef SERVICCE_FUNC_HEADER
  1227.     #define SERVICCE_FUNC_HEADER
  1228.  
  1229.  
  1230. // ==================================================
  1231. #define USE_SPRINT_CONV
  1232. #define USE_NUM_TO_STR_FUNC
  1233. #define USE_T1_AUToPRESCALER
  1234. // ==================================================
  1235.  
  1236. // ------------------------------------------------------
  1237. #ifdef USE_MAX543
  1238. #define MAX543DDRX          DDRB
  1239. #define MAX543PORTX         PORTB
  1240.  
  1241. #define MAX543CLK_BIT       0x02 //1
  1242. #define MAX543SRI_BIT       0x04 //2
  1243. #define MAX543LOAD_BIT      0x08 //3
  1244.  
  1245. #define MAX543_CLK_HIGH()   (MAX543PORTX |= MAX543CLK_BIT)
  1246. #define MAX543_CLK_LOW()    (MAX543PORTX &= ~MAX543CLK_BIT)
  1247.  
  1248. #define MAX543_SRI_HIGH()   (MAX543PORTX |= MAX543SRI_BIT)
  1249. #define MAX543_SRI_LOW()    (MAX543PORTX &= ~MAX543SRI_BIT)
  1250.  
  1251. #define MAX543_LOAD_HIGH()  (MAX543PORTX |= MAX543LOAD_BIT)
  1252. #define MAX543_LOAD_LOW()   (MAX543PORTX &= ~MAX543LOAD_BIT)
  1253.  
  1254. #define SET_MAX543_INIT()   (MAX543DDRX |= MAX543CLK_BIT | MAX543SRI_BIT | MAX543LOAD_BIT)
  1255.  
  1256. #define DEL2CYCLES()        __asm__ __volatile__( "rjmp 1f\n 1:" );
  1257. extern void MAX543( uint16_t u16Val );
  1258. #endif
  1259.  
  1260. // ------------------------------------------------------
  1261. #ifdef USE_LEDSHOWBYTE
  1262. #define Bit0_5_DDRX DDRC
  1263. #define Bit6_7_DDRX DDRD
  1264. #define Bit0_5_PORT DDRC
  1265. #define Bit6_7_PORT PORTD
  1266. #define Bit0_5_MSK  0b00111111
  1267. #define Bit6_7_MSK  0b11000000
  1268. extern void LEDShowByte( uint8_t u8Byte );
  1269. #endif
  1270.  
  1271. // ------------------------------------------------------
  1272. #ifdef USE_ADC
  1273. extern uint16_t ADC_10Bit(uint8_t u8Chan);
  1274. #endif
  1275.  
  1276. // ------------------------------------------------------
  1277. #ifdef USE_PWM_T2
  1278. extern void ServoPWM_T2_Init(void);
  1279. #endif
  1280.  
  1281. // ------------------------------------------------------
  1282. #ifdef USE_T1_AUToPRESCALER
  1283. extern void SelectBestPreScaler_T1( float fSollFrq );
  1284. #endif
  1285.  
  1286. // ------------------------------------------------------
  1287. #ifdef USE_T2_AUToPRESCALER
  1288. extern void SelectBestPreScaler_T2( float fSollFrq );
  1289. #endif
  1290.  
  1291.  
  1292. #ifdef USE_NUM_TO_STR_FUNC
  1293. #define FLOAT_PRAEDIGITS_MAX    5
  1294. #define FLOAT_DIGITS_MAX        1 // DIgits nach //dtostrf(fVal,NUMMAX, DIGITS_MAX, gcaNumStr);
  1295. extern char* FloatToNumStr(double fVal);
  1296. extern char* LongToNumStr(int32_t lVal);
  1297. extern char* ULongToNumStr(uint32_t ulVal);
  1298. #endif
  1299.  
  1300.  
  1301. #ifdef USE_SPRINT_CONV
  1302. extern void SLongToNumStr(int32_t lVal);
  1303. extern void SFloatToNumStr(double fVal);
  1304. #endif
  1305.  
  1306. #endif // SERVICE_FUNC_HEADER
  1307.  
  1308.  
  1309.  
  1310. ==================================================
  1311.  Service.c
  1312. ==================================================
  1313. //------------------------------------------------------------------------------
  1314. // Programmed by Christof Ermer 12.2019
  1315. //------------------------------------------------------------------------------
  1316.  
  1317. #include "main.h"
  1318. #include "ServiceFunc.h"
  1319.  
  1320.  
  1321. //MAX7219_Write(1, gu8Morse_Flags_Rx );
  1322.  
  1323.  
  1324. #ifdef USE_SPRINT_CONV
  1325. // **********************************************
  1326. void SLongToNumStr(int32_t lVal)
  1327. // **********************************************
  1328. {
  1329. sprintf(gcaNumStr,"%ld", lVal);  //Ulong = %ld
  1330. };
  1331.  
  1332. // **********************************************
  1333. void SFloatToNumStr(double fVal)
  1334. // *************
  1335. {
  1336. sprintf(gcaNumStr,"%.1f", fVal);
  1337. };
  1338. #endif
  1339.  
  1340.  
  1341. #ifdef USE_NUM_TO_STR_FUNC
  1342. // **********************************************
  1343. char* FloatToNumStr(double fVal)
  1344. // *************
  1345. {
  1346. dtostrf(fVal, FLOAT_PRAEDIGITS_MAX, FLOAT_DIGITS_MAX, gcaNumStr ); //[-]d.ddd
  1347. return gcaNumStr;
  1348. };
  1349.  
  1350. // **********************************************
  1351. char* LongToNumStr(int32_t lVal)
  1352. // **********************************************
  1353. {
  1354. ltoa(lVal, gcaNumStr, 10 );
  1355. return gcaNumStr;
  1356. };
  1357.  
  1358. // **********************************************
  1359. char* ULongToNumStr(uint32_t ulVal)
  1360. // **********************************************
  1361. {
  1362. ultoa(ulVal, gcaNumStr, 10 );
  1363. return gcaNumStr;
  1364. };
  1365. #endif
  1366.  
  1367.  
  1368. #ifdef USE_T2_AUToPRESCALER
  1369. // ********************************************
  1370. void SelectBestPreScaler_T2( float fSollFrq )
  1371. // ********************************************
  1372. {
  1373. fSollFrq*= 2;   // Toogle = / 2
  1374. if( (F_CPU / 1 / fSollFrq ) > 0xFF)
  1375.     {
  1376.     if( (F_CPU / 8 / fSollFrq ) > 0xFF)
  1377.         {
  1378.         if( (F_CPU / 32 / fSollFrq ) > 0xFF)
  1379.             {
  1380.             if( (F_CPU / 64 / fSollFrq ) > 0xFF)
  1381.                 {                      
  1382.                 if( (F_CPU / 128 / fSollFrq ) > 0xFF)
  1383.                     {                      
  1384.                     if( (F_CPU / 256 / fSollFrq )  > 0xFF)
  1385.                         {
  1386.                         TCCR2B = (1<< CS22) | (1<< CS21) | (1<< CS20); //CTC 1024
  1387.                         OCR2A =  round (F_CPU / 1024 / fSollFrq);
  1388.                         }
  1389.                     else
  1390.                         {              
  1391.                         TCCR2B = (1<< CS22) | (1<< CS21); //CTC 256
  1392.                         OCR2A =  round (F_CPU / 256 / fSollFrq);
  1393.                         };
  1394.                     }
  1395.                 else
  1396.                     {
  1397.                     TCCR2B = (1<< CS22) | (1<< CS20); //CTC 128
  1398.                     OCR2A =  round (F_CPU / 128 / fSollFrq);
  1399.                     };
  1400.                 }
  1401.             else
  1402.                 {
  1403.                 TCCR2B = (1<< CS22); //CTC 64
  1404.                 OCR2A =  round (F_CPU / 64 / fSollFrq);
  1405.                 };
  1406.             }
  1407.         else   
  1408.             {
  1409.             TCCR2B = (1<< CS21)| (1<< CS20); //CTC 32
  1410.             OCR2A =  round (F_CPU / 32 / fSollFrq);
  1411.             };
  1412.         }
  1413.     else
  1414.         {
  1415.         TCCR2B = (1<< CS21); //CTC 8
  1416.         OCR2A =  round (F_CPU / 8 / fSollFrq);
  1417.         }  
  1418.     }
  1419. else
  1420.     {
  1421.     TCCR2B = (1<< CS20); //CTC 1
  1422.     OCR2A =  round (F_CPU / fSollFrq); // /1
  1423.     };
  1424. };
  1425. #endif
  1426.  
  1427.  
  1428.  
  1429. #ifdef USE_T1_AUToPRESCALER
  1430. // ********************************************
  1431. void SelectBestPreScaler_T1( float fSollFrq )
  1432. // ********************************************
  1433. {
  1434. fSollFrq*= 2;   // Toogle = / 2
  1435. if( (F_CPU / 1 / fSollFrq ) > 0xFFFF)
  1436.     {
  1437.     if( (F_CPU / 8 / fSollFrq ) > 0xFFFF)
  1438.         {
  1439.         if( (F_CPU / 64 / fSollFrq ) > 0xFFFF)
  1440.             {
  1441.             if( (F_CPU / 256 / fSollFrq )  > 0xFFFF)
  1442.                 {
  1443.                 TCCR1B = (1<< WGM12) | (1<<CS12) | (1<< CS10); //CTC 1024
  1444.                 OCR1A =  round (F_CPU / 1024 / fSollFrq);
  1445.                 }
  1446.             else
  1447.                 {              
  1448.                 TCCR1B = (1<< WGM12) | (1<<CS12); //CTC 256
  1449.                 OCR1A =  round (F_CPU / 256 / fSollFrq);
  1450.                 };
  1451.             }
  1452.         else
  1453.             {
  1454.             TCCR1B = (1<< WGM12) | (1<<CS11) | (1<<CS10); //CTC 64
  1455.             OCR1A =  round (F_CPU / 64 / fSollFrq);
  1456.             };
  1457.         }
  1458.     else   
  1459.         {  
  1460.         TCCR1B = (1<< WGM12) | (1<<CS11); //CTC 8
  1461.         OCR1A =  round (F_CPU / 8 / fSollFrq);
  1462.         };         
  1463.     }
  1464. else
  1465.     {
  1466.     TCCR1B = (1<< WGM12) | (1<<CS10); //CTC 1
  1467.     OCR1A =  round (F_CPU / fSollFrq); // /1
  1468.     };
  1469. };
  1470. #endif
  1471.  
  1472.  
  1473.  
  1474. #ifdef USE_MAX543
  1475. // ******************************
  1476. void MAX543( uint16_t u16Val )
  1477. // ******************************
  1478. {
  1479. Toggle_Bit(1);
  1480.  
  1481. uint8_t u8NN=11;
  1482. SET_MAX543_INIT();
  1483.  
  1484. MAX543_CLK_LOW(); //Startcondition
  1485. MAX543_LOAD_HIGH(); //Startcondition
  1486.  
  1487. do
  1488.     {
  1489.     if( u16Val & (1 << u8NN) )
  1490.         {
  1491.         MAX543_SRI_HIGH();
  1492.         }
  1493.     else
  1494.         {
  1495.         MAX543_SRI_LOW();
  1496.         };
  1497.     _delay_us(1);
  1498.     MAX543_CLK_HIGH(); 
  1499.     _delay_us(1);
  1500.     MAX543_CLK_LOW();
  1501.    
  1502.     }while( u8NN-- );
  1503. MAX543_LOAD_LOW(); 
  1504. };
  1505. #endif
  1506.  
  1507.  
  1508.  
  1509. #ifdef USE_PWM_T2
  1510. // ***************************
  1511. void ServoPWM_T2_Init(void)
  1512. // ***************************
  1513. {
  1514. DDRB |= SERVO_T2_PWM_BIT;
  1515. //F_CPU / 1024 / 256--> 61Hz = 16.384 mSekunden/Periode bei 256erTeilung
  1516. // 1MS --> 256 /  16.384 = 15.625   ~16
  1517. OCR2A = PM1MS;  //20ms-_> 256/20 = 12.8
  1518. TCCR2A = _BV(WGM21) | _BV(WGM20) | _BV(COM2A1); // FAST PWM  / Clear by Match
  1519. TCCR2B =_BV(CS22) | _BV(CS21) | _BV(CS20);  // x07 setzt / 1024
  1520. };
  1521. #endif
  1522.  
  1523.  
  1524.  
  1525. #ifdef USE_LEDSHOWBYTE
  1526. // *************************************
  1527. void LEDShowByte( uint8_t u8Byte )
  1528. // *************************************
  1529. {
  1530. Bit0_5_DDRX |= Bit0_5_MSK;
  1531. Bit6_7_DDRX |= Bit6_7_MSK;
  1532. Bit0_5_PORT = (Bit0_5_PORT & ~ Bit0_5_MSK) | (u8Byte & Bit0_5_MSK);
  1533. Bit6_7_PORT = (Bit6_7_PORT & ~ Bit6_7_MSK) | (u8Byte & Bit6_7_MSK);
  1534. };
  1535. #endif
  1536.  
  1537.  
  1538.  
  1539. #ifdef USE_ADC
  1540. /*
  1541. ADC_INTERN-----ADC_INTERN-----ADC_INTERN---ADC_INTERN
  1542. ADC_EXTERNREF_USED_ENABLED
  1543. PRESCALER 3,6864 /  32 = 115200 50-200Khz gewünscht
  1544. REM ADC4-ADC5 = 8 BIT;
  1545. 4+2 Channel.
  1546. */
  1547. //****************************************************************
  1548. uint16_t ADC_10Bit(uint8_t u8Chan)
  1549. //****************************************************************
  1550. {
  1551. DDRC &= ~ _BV(u8Chan);   //port A Chanel Bit Input  
  1552. PORTC &= ~ _BV(u8Chan); //Wegen Pullup abschalten
  1553.   // Activate ADC with Prescaler 16 --> 16Mhz/128 = 125 khz
  1554. ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) |_BV(ADPS0);  
  1555.  // Select pin ADC0 using MUX
  1556. ADMUX = (1 << REFS0) | u8Chan;  //Interne VCC + 100nF an AREF, KEIN VCC an AREF
  1557.     //Start conversion
  1558. ADCSRA |= _BV(ADSC);  
  1559. while( ADCSRA & _BV(ADSC) ) // wait until conversion completed
  1560.     {
  1561.     wdt_reset();
  1562.     };     
  1563. return ADC;// get converted value
  1564. };
  1565. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement