|
|
View previous topic :: View next topic |
Author |
Message |
inservi
Joined: 13 May 2007 Posts: 128
|
DCF77 decoder |
Posted: Sun Oct 07, 2007 10:55 am |
|
|
Hello, here is a simple DCF77 decoder with little sample.
-----------------------------------------------------------------------
UPDATE The October 08 2007 changing :
#define DCF77ValuesDayOfWeek 5 // ( 3 was a fault )
-----------------------------------------------------------------------
the October 12 2007
some little enhancement in DCF77Decoding.c
-----------------------------------------------------------------------
the October 14 2007
little correction in weekday
-----------------------------------------------------------------------
the October 18 2007
Improvement to the timer management.
Simple sample for how to make a zero drift timer with just some defines
and one set_Timer () at the start of interrupt.
1 - setup the timer for a time overflow a few bigger than the needed one
2 - type the parameters in the #defines as in this sample
3 - add the 'set_TimerX( DCF77SetTimer ); ' at the beginning of the interrupt
-----------------------------------------------------------------------
the june 19 2008
improvement for zero drift timer from ckielstra
-----------------------------------------------------------------------
Code: | ////////////////////////////////////////////////////////////////////////////
// DCF77 DECODER //
// //
// Writen by Daniel ROBERT V1.0 07 october 2007 //
// //
// //
// Although the radio transmission of DCF77 signal is not //
// highly reliable, it can be practical to use it for time //
// initialisation. //
// It is appropriate then to manage the real houre progression //
// with an autonomous clock. //
// //
// If receiver DCF77 is used to maintain the hour continually, //
// it is necessary to check at each end of cycle ( each minute ) //
// if the new hour is well corresponding to the previous one plus //
// one minute. In any way an autonomous (internal) clock is needed //
// to allows to maintain the hour right for several minute because //
// of some parasite can easily block the reception for a long time. //
// //
// In some environments, it is difficult to get a right signal //
// //
// Three led are used for monitoring the reception progress. //
// LED_Error is lighting when radio error //
// LED_ZERO is flashing when a zero is received //
// LED_ONE is flashing when a ONE is received //
// //
// LED_ZERO and LED_ONE are lighting together (1 sec) at //
// the start of cycle //
// //
// For demo, the result is sended to hyperterminal in VT100 mode //
// //
// At starting, nothink appens until the 'start' is received (that //
// can take almost one minute) Then the two data led are blinking //
// togther 1 seconde. After that, the led ONE and ZERO must blink //
// one at the time, until the end of cycle. In case of radio error, //
// the Error led start lighting until the next start. Then the cycle //
// is restarting. //
// //
// This code will easily work on most PIC with CCS C V 3.x and V 4.x //
// //
// I'm working to changing 'int DCF77Bits[59]' array for use only //
// 59 bits rather than 59 bytes. //
// //
////////////////////////////////////////////////////////////////////////////
#include "18F2620.h"
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV21 //Brownout reset at 2.1V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES FCMEN //Fail-safe clock monitor enabled
//#FUSES XINST //Extended set extension and Indexed Addressing mode enabled
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
#define FOSC 20000000 // used for setup delay and calculate the zero drift timmer
#define DCF77TimerDepth 65536 // for 16 bit timer
#define DCF77TimerPrescaler 1 // for prescaler div by 1
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
#use delay(clock=FOSC)
#define LCD_TX PIN_C6
#define LCD_RX PIN_C6
#define LCD_BAUD 4800
#define RADIO_PORT PIN_C2 // input from DCF77 receiver
#define LED_Error PIN_A2 // led indicating DCF77 error
#define LED_ZERO PIN_A3 // led indicating a zero from DCF77
#define LED_ONE PIN_A4 // led indicating a one from DCF77
#define RADIO_PORT_HIGH input(RADIO_PORT)
#define RADIO_PORT_LOW !input(RADIO_PORT)
#use RS232(baud=LCD_BAUD, xmit=LCD_TX , rcv=LCD_RX )
#define VT100LF "%c[B", 27 // "%c%c",13,10
#define VT100CLS "%c[2J", 27 //"%c",12
#define VT100HOME "%c[H", 27
// --RTC--
#define RadioLength0 10 // not used - length of pulse for a zero
#define RadioLength1 15 // 150 ms minimum (normalement 160 minimum 200 tipicaly)
#define RadioLengthStart 100 // normaly, 1 sec then 100
#define RadioStartMinute 21 // position of first bit of minute in dcf77 scheme
#define RadioParityMinute 28 // same story for next element
#define RadioStartHeure 29 // "
#define RadioParityHeure 35 // "
#define RadioStartDay 36 // "
#define RadioStartDayOfWeek 42 // "
#define RadioStartMonth 45 // "
#define RadioStartYear 50 // "
#define RadioParity3 58 // "
#define DCF77ValuesMinute 0 // element number is scheme
#define DCF77ValuesHour 2 // same story for next element
#define DCF77ValuesDay 4 // "
#define DCF77ValuesDayOfWeek 5 // "
#define DCF77ValuesMonth 6 // "
#define DCF77ValuesYear 7 // "
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
#define DCF77InteruptTime 0.01 // sec
#define DCF77SetTimer (int16)( DCF77TimerDepth * DCF77TimerPrescaler ) - (int16)( DCF77InteruptTime * (FOSC / 4) )
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
// --------- GLOBAL DECLARATION --------------
int8 DCF77Bits[59] = {0} ; // table for put all DCF77 bits for one cycle
int8 const DCF77BitWeight[8] = {1,2,4,8,10,20,40,80};
char const DOW[7][8] = { {"Mon\0"}, {"Tues\0"}, {"Wednes\0"}, {"Thurs\0"}, {"Fri\0"}, {"Satur\0"}, {"Sun\0"} } ;
// | 128 for set the bit 7 for indicate that it is a parity bit
int8 const DCF77Scheme[9]= { RadioStartMinute, RadioParityMinute | 128, RadioStartHeure, RadioParityHeure | 128,
RadioStartDay, RadioStartDayOfWeek, RadioStartMonth, RadioStartYear, RadioParity3 | 128 } ;
int8 DCF77Values[9] = {0} ;
int8 DCF77Sec ;
int8 DCF77LastDate = 0 ;
short DCF77TimeOk = false, DCF77CycleOK = false ;
int8 LastRadioTime = 0 ;
int8 DCF77Pulse = 0 ; // lenght of pulse is hundredth (sec/100) of Sec
short RadioBit , RadioParity ;
int8 DCF77BitNbr = 0 ;
short RadioWaitStart = true, RadioWaitHight, RadioHightMesure ;
int8 heure = 0, Minute = 0, Seconde = 0 ;
int8 day = 0, dayOfWeek = 0, month = 0, year = 0 ;
int8 Sec100 ;
short SecondeFlag = 0, MinuteFlag = 0 ;
short RadioError = false ;
#int_timer0
void timer0_isr() {
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
//set_Timer0( DCF77SetTimer );
set_timer0( get_timer0() + DCF77SetTimer ) // enhancement from ckielstra
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
// -- autonomous clock --
if (++Sec100 == 100) {
Sec100 = 0 ;
SecondeFlag = 1 ;
if (++DCF77Sec == 60) DCF77Sec = 0 ; // count hundredth (1/100) of second for DCF77
if (++Seconde == 60) { // hours
Seconde = 0;
MinuteFlag = 1;
if (++Minute == 60) { // hours
Minute = 0 ;
if (++heure == 24) heure = 0 ; // days
}
}
}
// --------------------
if (++DCF77Pulse >= RadioLengthStart) { //if low for at least 1 sec then start or error. Assume start
RadioWaitStart = true ;
RadioWaitHight = false ;
RadioHightMesure = false ;
}
if (RadioWaitStart) { // wait for starting cycle. the length is at least 1 second
if ( RADIO_PORT_HIGH ) {
DCF77Pulse = 0 ; // reset if in high pulse ( after an error ) for mesure from start of zero
}
if (DCF77Pulse >= RadioLengthStart) { // starting cycle
RadioError = false ;
output_high(LED_ZERO); //
output_high(LED_ONE); // At start, the two led (one and zero) are blinking together
DCF77Pulse =0 ; // reset hundredth count
RadioWaitStart = false ;
RadioWaitHight = true ; // past to next step wait for begin of hight pulse
DCF77BitNbr = 0 ;
DCF77Sec = 59 ; // init secondes
Sec100 = 30 ;
}
}
if (RadioWaitHight) { // wait for start of hight pulse
if ( RADIO_PORT_HIGH ) {
DCF77Pulse = 0 ;
RadioWaitHight = false ;
RadioHightMesure = true ;
output_low(LED_ZERO);
output_low(LED_ONE);
}
}
if (RadioHightMesure) { // mesure the lengh of higth pulse
if ( RADIO_PORT_LOW ) { // end of high pulse, now DCF77Pulse contain the length of high pulse
RadioBit = (DCF77Pulse >= RadioLength1) ; // if DCF77 high pulse is greater than 160mS is 1 else is 0
if ( DCF77Pulse > 25 || DCF77Pulse < 8 ) { // if DCF77 high pulse is greater than 210mS or smaller 90mS then error
RadioError = true ;
RadioWaitStart = true ; // restart the waiting for start pulse (no signal for 1 sec)
}
DCF77Pulse = 0 ; // reset counter for pulse length
DCF77Bits[DCF77BitNbr] = RadioBit ; // put bit into table
if (++DCF77BitNbr == 59) { // if end of cycle
RadioWaitStart = true ;
DCF77CycleOK = true ;
}
RadioHightMesure = false ;
RadioWaitHight = !RadioWaitStart ; // back to wait for next hight pulse if cycle not finished and no error
// --- can be deleted --- juste for debugging
output_bit(LED_ZERO, !RadioBit ) ;
output_bit(LED_ONE, RadioBit ) ;
// ----------------------
}
}
}
#include <calcDCF77.c>
void StartTimer() {
Sec100 = 0 ;
set_Timer0( DCF77SetTimer );
enable_interrupts(INT_TIMER0);
}
void StopTimer() {
DISABLE_INTERRUPTS(INT_TIMER0);
}
int DCF77DateInt() {
return(DCF77Values[DCF77ValuesDay]+DCF77Values[DCF77ValuesMonth]+DCF77Values[DCF77ValuesYear]);
}
void fAffTime() {
output_bit(LED_Error, RadioError);
printf("\r");
printf("%2u:%02u:%02u ", Heure , Minute, Seconde );
}
void fAffDate() {
printf("\n\r"); // next line
printf( "%s", DOW[dayOfWeek-1] );
printf(" %02u/%02u/%02u", day, month, year );
DCF77LastDate = DCF77DateInt();
printf(VT100HOME); // home
}
void main() {
// --INIT RTC--
setup_wdt(WDT_OFF);
setup_timer_0( RTCC_INTERNAL | RTCC_DIV_1 ); // 13.1 mS
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
// ------------
setup_adc_ports(NO_ANALOGS);
delay_ms(100) ;
printf(VT100CLS) ;
printf("DCF77 Clock(c)IS");
delay_ms(1000);
// initialise time for test
Heure = 10;
Minute = 26 ;
Seconde = 0 ;
enable_interrupts(GLOBAL);
StartTimer() ;
printf(VT100CLS); // Clear screen
while (true) {
if ( DCF77CycleOK ) { // a complete cycles is finished
DCF77Decoding( DCF77ValuesMinute, DCF77ValuesYear ); // it is possible to ask decoding of a part of received data
// after testing of DCF77BitNbr
// if DCF77BitNbr is >= DCF77ValuesDay then you
// can already decode minutes and hours
DCF77CycleOK = false ; // for decoding DCF77 only one time when a cycle is finished
if ( DCF77TimeOk ) { // if no parity errors
DCF77TimeOk = false ;
Seconde = DCF77Sec ;
Minute = DCF77Values[DCF77ValuesMinute] ;
Heure = DCF77Values[DCF77ValuesHour] ;
day = DCF77Values[DCF77ValuesDay] ;
dayOfWeek = DCF77Values[DCF77ValuesDayOfWeek] ;
month = DCF77Values[DCF77ValuesMonth] ;
year = DCF77Values[DCF77ValuesYear] ;
if ( DCF77LastDate != DCF77DateInt() ) fAffDate() ; //
}
}
if ( SecondeFlag ) { // refresh time each seconds
fAffTime();
SecondeFlag = 0;
}
}
} |
And calcDCF77.c
Code: |
void DCF77Decoding( int first, int last ) {
int i,j, DCF77BitWeightSubscr ;
int calcStart, calcEnd ;
short parityTest ;
RadioError = false ;
for( j=first; j <= last; j++ ) {
DCF77Values[j] = 0 ;
calcStart = DCF77Scheme[j] ;
calcEnd = DCF77Scheme[j+1] ;
parityTest = bit_test( calcEnd, 7 ) ;
bit_clear(calcEnd, 7 );
DCF77BitWeightSubscr = 0 ;
for( i=calcStart; i < calcEnd; i++ ) {
if ( DCF77Bits[i] ) {
DCF77Values[j] += DCF77BitWeight[DCF77BitWeightSubscr] ;
RadioParity = !RadioParity ;
}
++DCF77BitWeightSubscr ;
}
if ( parityTest ) {
RadioError = ( RadioParity != DCF77Bits[calcEnd] ) ;
RadioParity = 0 ;
j++ ;
}
if ( RadioError ) break ;
}
// -- The autonomous clock will add a minute because second is just set at 0 then minute - 1 ---
// not necessary without autonomous clock
if ( !RadioError ) {
if (!DCF77Values[DCF77ValuesMinute]--) {
DCF77Values[DCF77ValuesMinute] = 59;
if(!DCF77Values[DCF77ValuesHour]--) DCF77Values[DCF77ValuesHour] = 23 ;
}
}
// --------------------------------------------------------------------------------------
DCF77TimeOk = !RadioError ;
}
|
Your commentary and/or suggestions are welcome.
dro. _________________ in médio virtus
Last edited by inservi on Mon May 19, 2008 4:14 am; edited 8 times in total |
|
|
inservi
Joined: 13 May 2007 Posts: 128
|
|
Posted: Mon Oct 08, 2007 3:31 am |
|
|
Hello,
The version with data stocked in bit is there ! (Is about less than 50 bytes of data saved).
--------------------------------------
little enhancement
Update the October 11 2007
removing 'day' from element to char const DOW and add one time in printf
--------------------------------------
--------------------------------------
BIG ERROR CORRECTING
the October 12 2007
added bit_clear(DCF77Bits[DCF77ByteNbr],DCF77BitNbr);
before DCF77Bits[DCF77ByteNbr] |= RadioBit<<DCF77BitNbr ;
some little enhancement in DCF77Decoding.c
--------------------------------------
the October 14 2007
little correction in weekday
--------------------------------------
-----------------------------------------------------------------------
the june 19 2008
improvement for zero drift timer from ckielstra
-----------------------------------------------------------------------
Code: | ////////////////////////////////////////////////////////////////////////////
// DCF77 DECODER //
// //
// Writen by Daniel ROBERT V1.1 08 october 2007 //
// //
// //
// Although the radio transmission of DCF77 signal is not //
// highly reliable, it can be practical to use it for time //
// initialisation. //
// It is appropriate then to manage the real houre progression //
// with an autonomous clock. //
// //
// If receiver DCF77 is used to maintain the hour continually, //
// it is necessary to check at each end of cycle ( each minute ) //
// if the new hour is well corresponding to the previous one plus //
// one minute. In any way an autonomous (internal) clock is needed //
// to allows to maintain the hour right for several minute because //
// of some parasite can easily block the reception for a long time. //
// //
// In some environments, it is difficult to get a right signal //
// //
// Three led are used for monitoring the reception progress. //
// LED_Error is lighting when radio error //
// LED_ZERO is flashing when a zero is received //
// LED_ONE is flashing when a ONE is received //
// //
// LED_ZERO and LED_ONE are lighting together (1 sec) at //
// the start of cycle //
// //
// For demo, the result is sended to hyperterminal in VT100 mode //
// //
// At starting, nothink appens until the 'start' is received (that //
// can take almost one minute) Then the two data led are blinking //
// togther 1 seconde. After that, the led ONE and ZERO must blink //
// one at the time, until the end of cycle. In case of radio error, //
// the Error led start lighting until the next start. Then the cycle //
// is restarting. //
// //
// This code will easily work on most PIC with CCS C V 3.x and V 4.x //
// //
////////////////////////////////////////////////////////////////////////////
#include "18F2620.h"
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV21 //Brownout reset at 2.1V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES FCMEN //Fail-safe clock monitor enabled
//#FUSES XINST //Extended set extension and Indexed Addressing mode enabled
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
#define FOSC 20000000 // used for setup delay and calculate the zero drift timmer
#define DCF77TimerDepth 65536 // for 16 bit timer
#define DCF77TimerPrescaler 1 // for prescaler div by 1
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
#use delay(clock=FOSC)
#define LCD_TX PIN_C6
#define LCD_RX PIN_C6
#define LCD_BAUD 4800
#define RADIO_PORT PIN_C2 // input from DCF77 receiver
#define LED_Error PIN_A2 // led indicating DCF77 error
#define LED_ZERO PIN_A3 // led indicating a zero from DCF77
#define LED_ONE PIN_A4 // led indicating a one from DCF77
#define RADIO_PORT_HIGH input(RADIO_PORT)
#define RADIO_PORT_LOW !input(RADIO_PORT)
#use RS232(baud=LCD_BAUD, xmit=LCD_TX , rcv=LCD_RX )
#define VT100LF "%c[B", 27 // "%c%c",13,10
#define VT100CLS "%c[2J", 27 //"%c",12
#define VT100HOME "%c[H", 27
// --RTC--
#define RadioLength0 10 // not used - length of pulse for a zero
#define RadioLength1 15 // 150 ms minimum (normalement 160 minimum 200 tipicaly)
#define RadioLengthStart 100 // normaly, 1 sec then 100
#define RadioStartMinute 21 // position of first bit of minute in dcf77 scheme
#define RadioParityMinute 28 // same story for next element
#define RadioStartHeure 29 // "
#define RadioParityHeure 35 // "
#define RadioStartDay 36 // "
#define RadioStartDayOfWeek 42 // "
#define RadioStartMonth 45 // "
#define RadioStartYear 50 // "
#define RadioParity3 58 // "
#define DCF77ValuesMinute 0 // element number is scheme
#define DCF77ValuesHour 2 // same story for next element
#define DCF77ValuesDay 4 // "
#define DCF77ValuesDayOfWeek 5 // "
#define DCF77ValuesMonth 6 // "
#define DCF77ValuesYear 7 // "
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
#define DCF77InteruptTime 0.01 // sec
#define DCF77SetTimer (int16)( DCF77TimerDepth * DCF77TimerPrescaler ) - (int16)( DCF77InteruptTime * (FOSC / 4) )
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
// --------- GLOBAL DECLARATION --------------
int8 DCF77Bits[9] = {0} ; // table for put all DCF77 bits for one cycle
int8 const DCF77BitWeight[8] = {1,2,4,8,10,20,40,80};
char const DOW[7][8] = { {"Mon\0"}, {"Tues\0"}, {"Wednes\0"}, {"Thurs\0"}, {"Fri\0"}, {"Satur\0"}, {"Sun\0"} } ;
// | 128 for set the bit 7 for indicate that it is a parity bit
int8 const DCF77Scheme[9]= { RadioStartMinute, RadioParityMinute | 128, RadioStartHeure, RadioParityHeure | 128,
RadioStartDay, RadioStartDayOfWeek, RadioStartMonth, RadioStartYear, RadioParity3 | 128 } ;
int8 DCF77Values[9] = {0} ;
int8 DCF77Sec ;
int8 DCF77LastDate = 0 ;
short DCF77TimeOk = false, DCF77CycleOK = false ;
int8 LastRadioTime = 0 ;
int8 DCF77Pulse = 0 ; // lenght of pulse is hundredth (sec/100) of Sec
short RadioBit , RadioParity ;
int8 DCF77BitNbr = 0, DCF77ByteNbr = 0 ;
short RadioWaitStart = true, RadioWaitHight, RadioHightMesure ;
int8 heure = 0, Minute = 0, Seconde = 0 ;
int8 day = 0, dayOfWeek = 0, month = 0, year = 0 ;
int8 Sec100 ;
short SecondeFlag = 0, MinuteFlag = 0 ;
short RadioError = false ;
#int_timer0
void timer0_isr() {
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
set_Timer0( get_timer0() + DCF77SetTimer ); // for exactly 100 mSec
//------------------- FOR EASY ZERO DRIFT TIMER -------------------
// -- autonomous clock --
if (++Sec100 == 100) {
Sec100 = 0 ;
SecondeFlag = 1 ;
if (++DCF77Sec == 60) DCF77Sec = 0 ; // count hundredth (1/100) of second for DCF77
if (++Seconde == 60) { // hours
Seconde = 0;
MinuteFlag = 1;
if (++Minute == 60) { // hours
Minute = 0 ;
if (++heure == 24) heure = 0 ; // days
}
}
}
// --------------------
if (++DCF77Pulse >= RadioLengthStart) { //if low for at least 1 sec then start or error. Assume start
RadioWaitStart = true ;
RadioWaitHight = false ;
RadioHightMesure = false ;
}
if (RadioWaitStart) { // wait for starting cycle. the length is at least 1 second
if ( RADIO_PORT_HIGH ) {
DCF77Pulse = 0 ; // reset if in high pulse ( after an error ) for mesure from start of zero
}
if (DCF77Pulse >= RadioLengthStart) { // starting cycle
RadioError = false ;
output_high(LED_ZERO); //
output_high(LED_ONE); // At start, the two led (one and zero) are blinking together
DCF77Pulse =0 ; // reset hundredth count
RadioWaitStart = false ;
RadioWaitHight = true ; // past to next step wait for begin of hight pulse
DCF77ByteNbr = 0 ;
DCF77BitNbr = 0 ;
DCF77Sec = 59 ; // init secondes
}
}
if (RadioWaitHight) { // wait for start of hight pulse
if ( RADIO_PORT_HIGH ) {
DCF77Pulse = 0 ;
RadioWaitHight = false ;
RadioHightMesure = true ;
output_low(LED_ZERO);
output_low(LED_ONE);
}
}
if (RadioHightMesure) { // mesure the lengh of higth pulse
if ( RADIO_PORT_LOW ) { // end of high pulse, now DCF77Pulse contain the length of high pulse
RadioBit = (DCF77Pulse >= RadioLength1) ; // if DCF77 high pulse is greater than 160mS is 1 else is 0
if ( DCF77Pulse > 25 || DCF77Pulse < 8 ) { // if DCF77 high pulse is greater than 210mS or smaller 90mS then error
RadioError = true ;
RadioWaitStart = true ; // restart the waiting for start pulse (no signal for 1 sec)
}
DCF77Pulse = 0 ; // reset counter for pulse length
bit_clear(DCF77Bits[DCF77ByteNbr],DCF77BitNbr);
DCF77Bits[DCF77ByteNbr] |= RadioBit<<DCF77BitNbr ; // put bit into table
if (++DCF77BitNbr == 8) {
DCF77BitNbr = 0 ;
++DCF77ByteNbr ;
}
if (DCF77ByteNbr == 7 && DCF77BitNbr == 3) { // if end of cycle (7*8) + 3 = 59
RadioWaitStart = true ;
DCF77CycleOK = true ;
}
RadioHightMesure = false ;
RadioWaitHight = !RadioWaitStart ; // back to wait for next hight pulse if cycle not finished and no error
// --- can be deleted --- juste for monitoring
output_bit(LED_ZERO, !RadioBit ) ;
output_bit(LED_ONE, RadioBit ) ;
// ----------------------
}
}
}
#include <calcDCF77-8.c>
void StartTimer() {
Sec100 = 0 ;
set_Timer0( DCF77SetTimer );
enable_interrupts(INT_TIMER0);
}
void StopTimer() {
DISABLE_INTERRUPTS(INT_TIMER0);
}
int DCF77DateInt() {
return(DCF77Values[DCF77ValuesDay]+DCF77Values[DCF77ValuesMonth]+DCF77Values[DCF77ValuesYear]);
}
void fAffTime() {
output_bit(LED_Error, RadioError);
printf("\r");
printf("%2u:%02u:%02u ", Heure , Minute, Seconde );
}
void fAffDate() {
printf("\n\r"); // next line
printf( "%sday", DOW[dayOfWeek-1] );
printf(" %02u/%02u/%02u", day, month, year );
DCF77LastDate = DCF77DateInt();
printf(VT100HOME); // home
}
void main() {
// --INIT RTC--
set_timer0(0) ;
setup_timer_0(RTCC_INTERNAL);
setup_timer_2(T2_DIV_BY_16,196,16);
// ------------
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(FALSE);
setup_timer_1(T1_DISABLED);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
delay_ms(100) ;
printf(VT100CLS) ;
printf("DCF77 Clock(c)IS");
delay_ms(1000);
// initialise time for test
Heure = 10;
Minute = 26 ;
Seconde = 0 ;
enable_interrupts(GLOBAL);
StartTimer() ;
printf(VT100CLS); // Clear screen
while (true) {
if ( DCF77CycleOK ) { // a complete cycles is finished
DCF77Decoding( DCF77ValuesMinute, DCF77ValuesYear ); // it is possible to ask decoding of a part of received data
// after testing of DCF77BitNbr
// if DCF77BitNbr is >= DCF77ValuesDay then you
// can already decode minutes and hours
DCF77CycleOK = false ; // for decoding DCF77 only one time when a cycle is finished
if ( DCF77TimeOk ) { // if no parity errors
DCF77TimeOk = false ;
Seconde = DCF77Sec ;
Minute = DCF77Values[DCF77ValuesMinute] ;
Heure = DCF77Values[DCF77ValuesHour] ;
day = DCF77Values[DCF77ValuesDay] ;
dayOfWeek = DCF77Values[DCF77ValuesDayOfWeek] ;
month = DCF77Values[DCF77ValuesMonth] ;
year = DCF77Values[DCF77ValuesYear] ;
if ( DCF77LastDate != DCF77DateInt() ) fAffDate() ; //
}
}
if ( SecondeFlag ) { // refresh time each seconds
fAffTime();
SecondeFlag = 0;
}
}
} |
And the calcDCF77-8.c
Code: | void calcIndices(int8 indice, int8 *ByteNbr, int8 *BitNbr) {
*ByteNbr= indice / 8 ;
*BitNbr = indice - ( *ByteNbr * 8 ) ;
}
void DCF77Decoding( int first, int last ) {
int8 i,j, DCF77BitWeightSubscr ;
int8 calcStart, calcEnd ;
short parityTest ;
int8 ByteNbr, BitNbr ;
RadioParity = 0 ;
RadioError = false ;
for( j=first; j <= last; j++ ) {
DCF77Values[j] = 0 ;
calcStart = DCF77Scheme[j] ;
calcEnd = DCF77Scheme[j+1] ;
parityTest = bit_test( calcEnd, 7 ) ;
bit_clear(calcEnd, 7 );
DCF77BitWeightSubscr = 0 ;
for( i=calcStart; i < calcEnd; i++ ) {
calcIndices( i, &ByteNbr, &BitNbr ) ;
if ( bit_test( DCF77Bits[ByteNbr], BitNbr ) ) {
DCF77Values[j] += DCF77BitWeight[DCF77BitWeightSubscr] ;
RadioParity = !RadioParity ;
}
++DCF77BitWeightSubscr ;
}
if ( parityTest ) {
calcIndices( calcEnd, &ByteNbr, &BitNbr ) ;
RadioError = ( RadioParity != bit_test( DCF77Bits[ByteNbr], BitNbr ) ) ;
RadioParity = 0 ;
j++ ;
}
if ( RadioError ) break ;
}
// -- The autonomous clock will add a minute because second is just set at 0 then minute - 1 ---
// not necessary without autonomous clock
if ( !RadioError ) {
if (!DCF77Values[DCF77ValuesMinute]--) {
DCF77Values[DCF77ValuesMinute] = 59;
if(!DCF77Values[DCF77ValuesHour]--) DCF77Values[DCF77ValuesHour] = 23 ;
}
}
// --------------------------------------------------------------------------------------
DCF77TimeOk = !RadioError ;
}
|
dro. _________________ in médio virtus |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|