DCF77 time Code generator

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi
i need to build a DCF77 time-code generator around atmega32

there are many projects and library codes for DECODING Dcf77 time code but i could not find any library for making it!!!

any helping hand?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

i need to build a DCF77 time-code generator around atmega32

Is the one in Germany not good enough for you?
Quote:
From Wikipedia, the free encyclopedia

Coordinates: 50°0′56″N 9°00′39″E
DCF77 in Mainflingen
Low cost DCF77 receiver
DCF77 range from Physikalisch-Technische Bundesanstalt

DCF77 is a longwave time signal and standard-frequency radio station. Its primary and backup transmitter are located in Mainflingen, about 25 km south-east of Frankfurt am Main, Germany. It is operated by Media Broadcast GmbH (previously a subsidiary of Deutsche Telekom AG), on behalf of the Physikalisch-Technische Bundesanstalt, Germany's national physics laboratory. DCF77 has been in service as a standard-frequency station since 1959; date and time information was added in 1973. The timestamp sent is either in UTC+1 or UTC+2 depending on daylight saving time.[1]

The 77.5 kHz carrier signal is generated from local atomic clocks that are linked with the German master clocks in Braunschweig. With a relatively high power of 50 kW, ...

So, you already have the atomic clocks and the 50kW transmitter tower?

Your new time--it is "needed" for an alternate universe?

Quote:

i could not find any library for making it!!!

http://www.lmgtfy.com/?q=dcf77+t...

http://www.changpuak.ch/electron...

Quote:
Homebrew DCF-77 Signal Generator

Time machine without the (difficult to obtain) flux capacitor

Warning WARNING - TRANSMITTING YOUR OWN TIME-SIGNAL IS EVIL.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Surely radio licensing in most countries would prevent you from broadcasting on this widely recognised frequency?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks for the quick reply!

Quote:

So, you already have the atomic clocks and the 50kW transmitter tower?

Your new time--it is "needed" for an alternate universe?


full of fun !!! :D :lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol:
BUT you misunderstood me!! let me clarify the issue!

i do not need to transmit DCF 77.5 KHZ signal !!!
i need to make the DCF 77 time Code
ONLY the Timecode!!!

as you may know the time code is 60 bit long containing date and time data.

i need a library code to convert
e.g friday 1/27/2012 23:12:12 to something like
00000011000000000110001000010000100000100000...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Look in Wikipedia. It describes the DCF77 protocol.

It is simple to do.

I know that I wrote a MSF60 'generator'. I might have written a DCF77 one at the same time.

Is this a school project?

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I know that I wrote a MSF60 'generator'. I might have written a DCF77 one at the same time.
David.

thanks David !
could you take a look to find the code and send it to me?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No. I can't remember how it works. You will have to study it and ask.

#include "mcu.h"
#include 
#if defined(__CODEVISIONAVR__)
#include "/src/gnuavr/lcd.h"
extern void lcd_init(char width);
#else
#include "lcd.h"
#endif

#define IRQPERIOD	1000		/* 1ms IRQ */

#if defined(CPUARM)
#define RELOAD ((IRQPERIOD*(SYSCLK/1000))/1000 - 1)
#define IRQ_NUM		4		// T0 CTC irq
#define IRQ_INIT1()	{T0MR0=RELOAD;T0MCR=3;T0TCR=1;}
#define IRQ_INIT2()	{REGISTER_ISR(4, IRQ_NUM);ENABLE_IRQ(IRQ_NUM);SEI();}
#define IRQ_SVC()	{T0IR=1;ACK_IRQ();}
#define RESET_TMR()	// {T0TCR=3; T0TCR=1;}
#define IO_INIT()

#if defined (LPC2148_h)
#define RAW                 (IO1PIN & (1<<25))
#else 
#define RAW                 (IO0PIN & (1<<1))
#endif
volatile int INTEGRATE, OUTDCF77, LED, SYNC;

#elif defined(AVR)
#define RELOAD ((IRQPERIOD*(SYSCLK/64))/1000000 - 1)
#if defined(_CHIP_ATMEGA32_)
#define IRQ_INIT1()	{TCCR0 = (1<<WGM01)|(3<<CS00);}
#define IRQ_NUM		TIM0_COMP
#define IRQ_INIT2()	{TIMSK=(1<<OCIE0);OCR0=RELOAD;SEI();}
#elif defined(_CHIP_ATMEGA328P_)
#define IRQ_INIT1()	{TCCR0A = (1<<WGM01); TCCR0B = (3<<CS00);}
#define IRQ_NUM		TIM0_COMPA
#define IRQ_INIT2()	{TIMSK0=(1<<OCIE0A);OCR0A=RELOAD;SEI();}
#else
#error
#endif
#define IRQ_SVC()	{}
#define RESET_TMR()	//{TCNT0=0;}
#define IO_INIT()       {DDRB = 0x07; DDRD = (1<<2)|(1<<4);}     // sense INT0 on o/p pin, DCF77OUT too

#define RAW                 (PIND & (1<<3))
#define INTEGRATE			PORTD.2
#define OUTDCF77			PORTD.4
#define LED                 PORTB.1
#define SYNC                PORTB.0

#else
#error duff CPU
#endif

#define setA(posn, val)		A[posn] = val
#define setB(posn, val)		B[posn] = val
#define setDCF(posn, val)	DCF77[posn] = val
#define readA(posn)			A[posn]
#define readB(posn)			B[posn]
#define readDCF(posn)		DCF77[posn]

extern void initstdio(void);
extern unsigned char bcd2bin(unsigned char n);
extern unsigned char bin2bcd(unsigned char n);

extern void auto_update(void);
extern unsigned int X(unsigned char posn, unsigned char bits);
extern unsigned char setmsf60(void);
extern unsigned char checkmsf60(void);
extern unsigned char W(unsigned char posn, unsigned char val, unsigned char bits);
extern unsigned char checkdcf77(void);
extern unsigned int Y(unsigned char posn, unsigned char bits);
extern void setDCF77fields(void);

volatile unsigned char A[60], B[60], DCF77[60], sec, min, hour, wkday, day, mon, year, dirty;
volatile unsigned int ovfs, msec, errors;
char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
char *mons[] = {"MMM", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
                "XXX", "XXX", "XXX"};
// char *dsts[] = {"GMT", "BST"};

#define TC 50
ISR(IRQ_NUM)
{
    unsigned char level = (RAW != 0);
    static unsigned char avg, state;
    static unsigned int gap, pulse;
    // integrate the signal with time constant TC
    if (level && avg < TC) avg++;
    if (!level && avg > 0) avg--;
    if (avg >= TC) INTEGRATE = 1;
    if (avg == 0) INTEGRATE = 0;
    level = INTEGRATE;
    // might just as well use ovfs for the pulse width
    if (state != level) {
        LED = (level != 0);
        state = level;
        if (level) pulse = ovfs;
        else {
            gap = ovfs;
            if (gap >= 490 && pulse >= 490) {
                RESET_TMR();
                sec = 1;
                msec = 0;
                dirty = 1;
                SYNC = 0;
            }
        }
        ovfs = 0;
    }                            
    else ++ovfs;
    if (++msec >= 1000)
        msec = 0;
    if (msec == 0) {
        auto_update();
//        setDCF77fields();
    }
    if (msec == 0 && sec != 59)
        OUTDCF77 = 0;
    if (msec == 100)
        OUTDCF77 = !readDCF(sec);
    if (msec == 200)
        OUTDCF77 = 1;
    if (msec == 50 && level)
        errors++;
    if (msec == 150)
        setA(sec, !level);
    if (msec == 250)
        setB(sec, !level);
    IRQ_SVC();
}

void init(void)
{
    char buf[] = "Hello MSF60";
    IO_INIT();
    IRQ_INIT1();
    IRQ_INIT2();
    lcd_init(16);
    lcd_puts(buf);
}

unsigned char oldsec = 61;
void main(void)
{
    unsigned char chk = 9, sync_hr = 99, sync_min = 99;
    char buf[20];
    init();
    while (1) {
        if (dirty) {
            dirty = 0;
            chk = checkmsf60();

            if (chk) {
                 sync_hr = hour;
                 sync_min = min;
                 setmsf60();
            }

/*
            printf("\r\nMSF60: %04X %02X %02X %02X %02X %02X chk:%d\r\n",
                   0x2000 + X(17, 8), X(25, 5), X(30, 6), X(36, 3), X(39, 6), X(45, 7), chk);
*/
        }
        if (sec != oldsec) {
            oldsec = sec;
            if (sec == 0) {
                lcd_clrscr();             // takes 2ms
                setDCF77fields();         // takes 1ms
            }
            if (sec == 1)
                chk = checkmsf60();
            lcd_gotoxy(0, 0);
/*
            if (sec == 30)
                sprintf(buf, "Sync at %02d:%02d    ", (int)sync_hr, (int)sync_min);
            else
*/
                sprintf(buf, "%s, %02d %s %04d ", days[wkday], day, mons[mon], 2000+year);
            lcd_puts(buf);
            lcd_gotoxy(0, 1);
            sprintf(buf, "%02d:%02d:%02d [%02d.%02d]", hour, min, sec, sync_hr, sync_min);
            lcd_puts(buf);
        }
    }
}

void auto_update(void)
{
        if (++sec >= 60) {
            SYNC = 1;
            sec = 0;
            if (++min >= 60) {
                min = 0;
                if (++hour >= 24) {
                    hour = 0;
                    if (++wkday > 6)
                        wkday = 0;
                    if (++day > 31) {
                        day = 1;
                        if (++mon > 12) {
                            mon = 1;
                            if (++year > 99)
                                year = 0;
                        }
                    }
                }
            }
        }
}

unsigned char goodbcd(unsigned char *pvar, unsigned char val, unsigned char max)
{
    unsigned char ret = 1;
    if ((val & 0x0F) > 0x09) ret = 0;
    if ((val & 0xF0) > 0x90) ret = 0;
    if (ret && val <= max) *pvar = bcd2bin(val);
    else ret = 0;
    return ret;
}

unsigned int X(unsigned char posn, unsigned char bits)
{
    unsigned int n = 0;
    while (bits--) {
        n <<= 1;
        n |= readA(posn++);
    }
    return n;
}

unsigned char setmsf60(void)
{
    unsigned char ret = 1;
        ret &= goodbcd(&year, X(17, 8), 0x99);
        ret &= goodbcd(&mon, X(25, 5), 0x12);
        ret &= goodbcd(&day, X(30, 6), 0x31);
        ret &= goodbcd(&wkday, X(36, 3), 0x07);
        ret &= goodbcd(&hour, X(39, 6), 0x23);
        ret &= goodbcd(&min, X(45, 7), 0x59);
    return ret;
}

unsigned char checkmsf60(void)
{
    unsigned char cnt, n, ret = 1;
    cnt = readB(54);
    for (n = 17; n <= 24; n++)
        cnt += readA(n);
    ret &= cnt;
    cnt = readB(55);
    for (n = 25; n <= 35; n++)
        cnt += readA(n);
    ret &= cnt;
    cnt = readB(56);
    for (n = 36; n <= 38; n++)
        cnt += readA(n);
    ret &= cnt;
    cnt = readB(57);
    for (n = 39; n <= 51; n++)
        cnt += readA(n);
    ret &= cnt;
    return ret;
}

unsigned int Y(unsigned char posn, unsigned char bits)
{
    unsigned int n = 0;
    while (bits--) {
        n <<= 1;
        n |= readA(posn + bits);
    }
    return n;
}

unsigned char W(unsigned char posn, unsigned char val, unsigned char bits)
{
    unsigned char n = bin2bcd(val), even = 0;
    while (bits--) {
        setDCF(posn++, n & 1);
        if (n & 1)
            even++;
        n >>= 1;
    }
    return even;
}

unsigned char checkdcf77(void)
{
    unsigned char cnt, n, ret = 1;
    cnt = 1;                    // make parity ODD
    for (n = 21; n <= 28; n++)
        cnt += readA(n);
    ret &= cnt;
    cnt = 1;
    for (n = 29; n <= 35; n++)
        cnt += readA(n);
    ret &= cnt;
    cnt = 1;
    for (n = 36; n <= 59; n++)
        cnt += readA(n);
    ret &= cnt;
    if (ret) {
        year = bcd2bin(Y(50, 8));
        mon = bcd2bin(Y(45, 5));
        day = bcd2bin(Y(36, 6));
        wkday = bcd2bin(Y(42, 3));
        hour = bcd2bin(Y(29, 6));
        min = bcd2bin(Y(21, 7));
    }
    return ret;
}

void setDCF77fields(void)
{
    unsigned char cnt;          // this takes almost 1000us
    W(17, 2, 2);                //MEZ
    W(20, 1, 1);                //start
    cnt = W(21, min, 7);        //
    W(28, cnt & 1, 1);          // P1
    cnt = W(29, hour, 6);       //
    W(35, cnt & 1, 1);          // P2
    cnt = W(36, day, 6);        //
    cnt += W(42, wkday, 3);     //
    cnt += W(45, mon, 5);       //
    cnt += W(50, year, 8);      //
    W(58, cnt & 1, 1);          // P3
}

unsigned char bcd2bin(unsigned char n)
{
    return (n>>4)*10 + (n & 0xF);
}

unsigned char bin2bcd(unsigned char n)
{
    return ((n/10)<<4) + n % 10;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

did you found anything , i need the same thing please

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why are you waking-up a thread that's been dead for 6 years?

 

Have you already tried all the suggestions made those 6 years ago?

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why do people dig up skeletons from my past?

 

If someone has a valid question,   please ask.    It might be interesting.

 

David.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Why do people dig up skeletons from my past?

Do you "know" Stormy Daniels, too?

 

david.prentice wrote:
It might be interesting.

If, indeed, it looks like the necromancer actualy studied the thread first...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Mon. Mar 19, 2018 - 07:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No,   I have never met Stormy Daniels.    Has she been to Wisconsin?

 

I suspect that mouradII has gone away.    We will await the future.

I wrote the code in #7 completely blind.    If there is a genuine interest,   I will buy a real DCF77 kitchen clock.    I could place it next to the MSF60 wall clock in my living room.

 

David.

 

Edit.    DCF77 is in Germany.    I should be able to receive a signal in Kent.     The OP does not have a German name.     I doubt if DCF77 reaches Egypt.

Last Edited: Mon. Mar 19, 2018 - 07:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
  I doubt if DCF77 reaches Egypt.

But remember that the topic of this thread is for a DCF77 generator - not a receiver ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
If, indeed, it looks like the necromancer actualy studied the thread first...

Well - I guess there's a first time for everything ...

 

frown

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...