- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 2 von 2

Thema: Auswertung eines DCF77-Signals mit Atmega32

  1. #1

    Auswertung eines DCF77-Signals mit Atmega32

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo Leute,

    versuche mich gerade daran das Signal eines DCF77-Moduls von Reichelt auszuwerten und die aktuelle Zeit per serielle Schnittstelle an einen Computer zu senden. Am PC empfange ich auch etwas, nur leider nicht die aktuelle Zeit. Er zählt einfach die Sekunden hoch und zeigt mir den aktuellen Stand an. Hier mal die main-Datei und die Dtaei in welcher das Signal ausgewertet wird:

    Code:
    /*
     * main.c
     *
     * Created: 27.02.2014 13:27:29
     *  Author: Jens
     *
     * This program receives the DCF77 signal from a DCF77-Module from Reichelt and evaluates the
     * received data. The calculated time will be transmitted to a computer via UART. The program
     * is written for an ATmega32 device
     *
     */ 
    
    #include "global.h"
    #include "uart.h"
    #include "DCF77.h"
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
    	char msgBuffer[100];
    	
    	// Initialize the UART-Interface with 4800 baud
    	init_UART(4800);
    	strcpy(msgBuffer, "*********** DCF77-Clock **************\n");
    	uart_write_msg(msgBuffer,strlen(msgBuffer));
    	
    	// Enable global interrupts
    	sei();
    	
    	// Start DCF77 clock
    	strcpy(msgBuffer, "Starting clock...");
    	uart_write_msg(msgBuffer,strlen(msgBuffer));
    	Start_Clock();
    	strcpy(msgBuffer, "Done\n");
    	uart_write_msg(msgBuffer,strlen(msgBuffer));
    	
    	while(1)
    	{
    		// Transmit actual time to the computer
    		sprintf(msgBuffer, "Time: %i:%i:%i \n", hh, mm, ss);
    		uart_write_msg(msgBuffer,strlen(msgBuffer));
    		
    		// Wait
    		_delay_ms(1000);
    	}
    	
    	return 0;
    }
    Code:
    /*
     * main.c
     *
     * Created: 27.02.2014 00:10:17
     *  Author: Jens
     *
     * This file includes control functions for the use of a DCF77 module from Reichelt
     *
     */ 
    
    #include "DCF77.h"
    #include "global.h"
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    volatile unsigned char ss   = 0;   // Seconds
    volatile unsigned char mm   = 0;   // Minutes
    volatile unsigned char hh   = 0;   // Hours
    
    // Bit-counter for RX bit
    volatile unsigned char rx_bit_counter = 0;
    
    // 64 Bit, for DCF77 used 59 Bits
    volatile unsigned long long dcf_rx_buffer = 0;
    
    // Help-counter for seconds
    volatile unsigned int h_ss = 0;
    
    // Help-variable for hour-change
    volatile unsigned int h_hh = 0;
    
    // Timer1 overflow Interrupt, triggered by 59. second or no received DCF77 signal
    ISR(TIMER1_OVF_vect)
    {
    	struct  DCF77_Bits *rx_buffer;
    	rx_buffer = (struct DCF77_Bits*)(char*)&dcf_rx_buffer;
    	
    	// Reset timer
    	TCNT1 = 65535 - (F_CPU / 1024);
    	
    	// If all 59 Bits and the parity's are correctly received, set clock to DCF77 signal
    	if ((rx_bit_counter == 59) && (flags.parity_P1 == rx_buffer->P1) && (flags.parity_P2 == rx_buffer->P2) && (flags.parity_P3 == rx_buffer->P3))
    	{
    		// Calculate minutes BCD to HEX
    		mm = rx_buffer->Min - ((rx_buffer->Min / 16) * 6);
    		
    		if(mm != 0)
    		{
    			mm--;
    		}
    		else
    		{
    			mm = 59; 
    			h_hh = 1;
    		}
    		
    		// Calculate hours BCD to HEX
    		hh = rx_buffer->Hour - ((rx_buffer->Hour / 16) * 6);
    
    		if(h_hh)
    		{
    			hh--;
    			h_hh = 0;
    		}
    
    		// Reset seconds to zero
    		ss = 59;
    		flags.dcf_sync = 1;
    	}
    	else
    	{
    		// Manually set the clock 
    		Add_one_Second();
    		flags.dcf_sync = 0;
    	}
    	
    	// Reset the RX Bit-Counter
    	rx_bit_counter = 0;
    	// Clear the RX buffer
    	dcf_rx_buffer = 0;
    }
    
    // Interrupt on INT0, DCF77 Module receives time information
    ISR(INT0_vect)
    {
    	// Evaluate pulse width
    	if(INT0_CONTROL == INT0_RISING_EDGE)
    	{
    		flags.dcf_rx ^= 1;
    		
    		// Calculate second help-counter
    		h_ss = h_ss + TCNT1 - (65535 - (F_CPU / 1024));
    		// Reset timer
    		TCNT1 = 65535 - (F_CPU / 1024);
    		
    		// Check if a second is over
    		if(h_ss > (F_CPU / 1024 / 100 * 90)) //90% from 1 second
    		{
    			Add_one_Second();
    			// Reset second help-counter
    			h_ss = 0;
    		}
    		
    		// Next interrupt with falling edge
    		INT0_CONTROL = INT0_FALLING_EDGE;
    	}
    	else
    	{
    		// Read pulse width from rising edge to falling edge
    		unsigned int pulse_wide = TCNT1;
    		// Reset timer
    		TCNT1 = 65535 - (F_CPU / 1024);
    		// Calculate second help-counter
    		h_ss = h_ss + pulse_wide - (65535 - (F_CPU / 1024));
    		
    		//Safe parity:
    		// Begin area P1/P2/P3
    		if((rx_bit_counter ==  21) || (rx_bit_counter ==  29) || (rx_bit_counter ==  36))
    		{
    			flags.parity_err = 0;
    		}
    		// Safe P1
    		if(rx_bit_counter ==  28)
    		{
    			flags.parity_P1 = flags.parity_err;
    		}
    		//Safe P2
    		if(rx_bit_counter ==  35)
    		{
    			flags.parity_P2 = flags.parity_err;
    		}
    		//Safe P3
    		if(rx_bit_counter ==  58)
    		{
    			flags.parity_P3 = flags.parity_err;
    		}
    		
    		// Check if a 0 or 1 is received
    		//0 = 100 ms
    		//1 = 200 ms
    		// > 150ms (15% from 1 second -> 150ms)
    		if(pulse_wide > (65535 - (F_CPU / 1024) / 100 * 85))
    		{
    			// Write a 1 into the dcf_rx_buffer at position rx_bit_counter
    			dcf_rx_buffer = dcf_rx_buffer | ((unsigned long long) 1 << rx_bit_counter);
    			//Toggle Help-Parity
    			flags.parity_err = flags.parity_err ^ 1;
    		}
    		
    		// Next interrupt with rising edge
    		INT0_CONTROL = INT0_RISING_EDGE;
    		// Inkrement RX Bit-Counter
    		rx_bit_counter++;
    	}
    }
    
    // Function to add a second to the actual time value
    void Add_one_Second (void)
    {
    	ss++;
    	
    	// Check if a minute is done
    	if (ss == 60)
    	{
    		ss = 0;
    		mm++;
    		
    		// Check if a hour is done
    		if (mm == 60)
    		{
    			mm = 0;
    			hh++;
    			
    			// Check if the day is finished
    			if (hh == 24)
    			{
    				hh = 0;
    			}
    		}
    	}
    };
    
    // Function to initialize and start the timer
    void Start_Clock (void)
    {
    	// Enable interrupt on DCF77 with rising edge
    	DCF77_INT_ENABLE();
    	INT0_CONTROL = INT0_RISING_EDGE;
    	
    	// Interrupt overflow enable
    	TIMSK1 |= (1 << TOIE1);
    	// Set prescaler to 1024
    	TCCR1B |= (1<<CS10 | 0<<CS11 | 1<<CS12);
    	TCNT1 = 65535 - (F_CPU / 1024);
    }
    Und der Header zur Signalauswertung:
    Code:
    /*
     * DCF77.h
     *
     * Created: 27.02.2014 10:20:46
     *  Author: Jens
     */ 
    
    
    #ifndef DCF77_H_
    #define DCF77_H_
    
    volatile unsigned char ss;	// Seconds
    volatile unsigned char mm;	// Minutes
    volatile unsigned char hh;	// Hours
    
    extern void Start_Clock (void); // Function to start the DCF77-Clock
    extern void Add_one_Second (void); // Function to add one second to the actual time
    
    // 64 Bit, for DCF77 used 59 Bits
    volatile unsigned long long dcf_rx_buffer;
    // RX Pointer (Counter)
    volatile extern unsigned char rx_bit_counter;
    // Help-Counter for seconds
    volatile unsigned int h_ss;
    
    // INT0 Interrupt definitions
    #define DCF77_INT_ENABLE()	GICR |= (1<<INT0);
    #define INT0_CONTROL		MCUCR
    #define INT0_FALLING_EDGE	0x02
    #define INT0_RISING_EDGE	0x03
    #define TIMSK1 				TIMSK
    
    //Structure of the dcf_rx_buffer
    struct  DCF77_Bits {
    	unsigned char M			    :1	;
    	unsigned char O1			:1	;
    	unsigned char O2			:1	;
    	unsigned char O3			:1	;
    	unsigned char O4			:1	;
    	unsigned char O5			:1	;
    	unsigned char O6			:1	;
    	unsigned char O7			:1	;
    	unsigned char O8			:1	;
    	unsigned char O9			:1	;
    	unsigned char O10			:1	;
    	unsigned char O11			:1	;
    	unsigned char O12			:1	;
    	unsigned char O13			:1	;
    	unsigned char O14			:1	;
    	unsigned char R			    :1	;
    	unsigned char A1			:1	;
    	unsigned char Z1			:1	;
    	unsigned char Z2			:1	;
    	unsigned char A2			:1	;
    	unsigned char S			    :1	;
    	unsigned char Min			:7	;// 7 Bits for minutes
    	unsigned char P1			:1	;// Parity minutes
    	unsigned char Hour			:6	;// 6 Bits for hours
    	unsigned char P2			:1	;// Parity hours
    	unsigned char P3			:1	;// Parity from P2
    };
    
    struct
    {
    	volatile char parity_err				:1	;// Help Parity
    	volatile char parity_P1					:1	;// Calculated Parity P1
    	volatile char parity_P2					:1	;// Calculated Parity P2
    	volatile char parity_P3					:1	;// Calculated Parity P3
    	volatile char dcf_rx					:1	;// A impulse is received
    	volatile char dcf_sync					:1	;// The clock was synchronized in the last minute
    }flags;
    
    #endif /* DCF77_H_ */
    Ich hoffe ihr könnt mir weiterhelfen

    Gruß
    Mister232

  2. #2
    RN-Premium User Fleißiges Mitglied
    Registriert seit
    19.05.2012
    Ort
    Sigmaringen
    Beiträge
    169
    C is nicht unbedingt mein Favorit... und ich kann mich sicher auch Täuschen...
    aber ich würde mal das genauer kontrollieren:
    if ((rx_bit_counter == 59) && (flags.parity_P1 == rx_buffer->P1) && (flags.parity_P2 == rx_buffer->P2) && (flags.parity_P3 == rx_buffer->P3))
    Anscheinend muss ja diese Bedingung nicht erfüllt sein... daher geht das Programm dazu über die sekunden "manuell" zu zählen.

    oder der Interrupt meldet nie, das die DCF ein Signal gesendet hat.
    JAAAA... Microchips kann man essen... aber der Geschmack ist furchtbar.

Ähnliche Themen

  1. Fourier Transformation eines Sinus Signals
    Von Kampi im Forum Kopfnüsse / Wissensquiz
    Antworten: 10
    Letzter Beitrag: 09.12.2013, 23:57
  2. Auswertung des DCF77 SIgnals
    Von Slader im Forum Elektronik
    Antworten: 7
    Letzter Beitrag: 18.07.2012, 16:47
  3. Filterung eines Signals
    Von CamilloN im Forum Elektronik
    Antworten: 4
    Letzter Beitrag: 26.02.2008, 14:05
  4. Auslesen eines frequenzmodulierten Signals mit RN-Control
    Von rovag im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 17.12.2007, 15:41
  5. Empfangen eines IR-Signals
    Von Festblatte im Forum Elektronik
    Antworten: 1
    Letzter Beitrag: 18.07.2007, 16:48

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test