⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcf77.c

📁 WWVB receiver using AVR.
💻 C
字号:
/* $Id: dcf77.c,v 1.10 2005/11/01 15:47:10 simimeie Exp $ * Functions for communicating with the DCF module and calculating time */ #define BV _BV#include <avr/io.h>#include <avr/signal.h>#include "dcf77.h"#include "timers.h"#include "ledmodule.h"#include "timeformat.h"#ifdef DCFDEBUG#include "debugconsole.h"#endif/* These two defines allow us to easily switch between inverted and * not-inverted output. */#define DCFHI BV(PIND2)#define DCFLO 0/* if the last bit was received more than 1.5 seconds ago, then this * signals the start of a minute. */#define BORDER_MINSTART ((3 * TICKSPERSECOND) / 2)#define BORDERU_1BIT ((24 * TICKSPERSECOND) / 100)#define BORDERL_1BIT ((16 * TICKSPERSECOND) / 100)#define BORDERU_0BIT ((14 * TICKSPERSECOND) / 100)#define BORDERL_0BIT (( 6 * TICKSPERSECOND) / 100)#define BITDINDEX(x) ((x & 0xF8) >> 3)#define getbit(x) (bitdata[BITDINDEX(x)] & BV(x & 0x07))#define getbitval(x) ((getbit(x) == 0) ? 0 : 1)static uint8_t bitdata[8];static uint8_t bitsrecvd;static uint8_t lastval;struct tickdata lastchange; /* "Timestamp" of last change */struct dcftime dcftime[2];uint8_t dcfvalid;uint8_t sumbits(uint8_t start, uint8_t end) {	uint8_t mult = 1;	uint8_t res = 0;	while (start <= end) {		res += getbitval(start) * mult;		if (mult == 8) {			mult = 10;		} else {			mult <<= 1; /*  * 2 */		}		start++;	}	return res;}uint8_t paritybits(uint8_t start, uint8_t end) {	uint8_t res = 0;	while (start <= end) {		if (getbit(start)) {			res = !res;		}		start++;	}	return res;}SIGNAL(SIG_INTERRUPT0) {	uint8_t val = PIND;	struct tickdata curticks;	uint16_t tickdiff;	gettickdata(&curticks);	val &= BV(PIND2);	if (val == lastval) { /* No change at all? why the IRQ then? */		return;	}	lastval = val;	tickdiff = (curticks.seconds - lastchange.seconds) * TICKSPERSECOND	         + (curticks.ticks - lastchange.ticks);	lastchange = curticks;	if (val == DCFHI) { /* Signal changed to high */		if (tickdiff > BORDER_MINSTART) { /* Start of a new minute */			led_statusleds &= (uint8_t)~led_status_dcfgood;			if (bitsrecvd == 59) {				/* Sanity checks */				if (getbit(0)) {					/* Bit 0 always has to be 0 */					bitsrecvd++;				}				if (!getbit(20)) {					/* Bit 20 always has to be 1 */					bitsrecvd++;				}				if (paritybits(21, 28) != 0) {					bitsrecvd++;				}				if (paritybits(29, 35) != 0) {					bitsrecvd++;				}				if (paritybits(36, 58) != 0) {					bitsrecvd++;				}				if (getbit(17) == getbit(18)) {					bitsrecvd++;				}				if (bitsrecvd == 59) {					struct brokentime bt;					/* None of the sanity checks failed					 * - time should be valid. */					led_statusleds |= led_status_dcfgood;					/* Decode data now */					dcfvalid = !dcfvalid;					bt.year  = sumbits(50, 57);					bt.month = sumbits(45, 49);					bt.day   = sumbits(36, 41);					bt.hour  = sumbits(29, 34);					bt.min   = sumbits(21, 27);					bt.sec   = 0;					dcftime[dcfvalid].timestamp = bttots(&bt);					dcftime[dcfvalid].ticksecs = curticks.seconds;					dcftime[dcfvalid].issummertime = getbit(17);					timers_zero();					gettickdata(&lastchange);				}			}#ifdef DCFDEBUG			debugconsole_printtext("\r\n");#endif			bitsrecvd = 0;		}	} else { /* Signal changed to low */#ifdef LEDMODULE		led_statusleds |= led_status_dcfbit;#endif		if (bitsrecvd > 60) { return; }		if ((tickdiff > BORDERL_1BIT)		 && (tickdiff < BORDERU_1BIT)) { /* valid '1' bit */			bitdata[BITDINDEX(bitsrecvd)] |= BV(bitsrecvd & 0x07);			bitsrecvd++;#ifdef DCFDEBUG			debugconsole_printtext("1");#endif		} else if ((tickdiff > BORDERL_0BIT)		 && (tickdiff < BORDERU_0BIT)) { /* valid '0' bit */			bitdata[BITDINDEX(bitsrecvd)] &= (uint8_t)~BV(bitsrecvd & 0x07);			bitsrecvd++;#ifdef DCFDEBUG			debugconsole_printtext("0");		} else {			debugconsole_printtext("X");#endif		}	}}void dcf77_init(void) {	/* Set the IRQ line so that we get an IRQ whenever it changes	 * its logical level (0 -> 1 or 1 -> 0) */	MCUCR |= BV(ISC00);	/* And allow IRQs from that port */	GICR |= BV(INTF0);	/* Enable PullUp on Port D pin 2. The Port is already a input on	 * startup. */	PORTD |= BV(PD2);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -