211 lines
5.5 KiB
C++
211 lines
5.5 KiB
C++
|
/*
|
|||
|
* DCF77.cpp
|
|||
|
*
|
|||
|
* Created: 19/12/2013 14:06:30
|
|||
|
* Author: Adrien
|
|||
|
*/
|
|||
|
|
|||
|
#include "DCF77.h"
|
|||
|
#include "timer.h"
|
|||
|
#include <avr/io.h>
|
|||
|
#include <avr/interrupt.h>
|
|||
|
#include <util/atomic.h>
|
|||
|
#include <util/delay.h>
|
|||
|
#include "LCD.h"
|
|||
|
|
|||
|
#define LCD_DEBUG false
|
|||
|
#define time_low_dcf77_min_0 80
|
|||
|
#define time_low_dcf77_max_0 120
|
|||
|
#define time_low_dcf77_min_1 180
|
|||
|
#define time_low_dcf77_max_1 220
|
|||
|
#define time_no_modulation 1000
|
|||
|
#define en_attente_de_signal 0
|
|||
|
#define decodage_en_cours 1
|
|||
|
#define decodage_effectuer 2
|
|||
|
#define decodage_erreur 3
|
|||
|
#define temps_haut_min 500
|
|||
|
#define temps_bas_min 20
|
|||
|
|
|||
|
|
|||
|
dcf77 atc_;
|
|||
|
//#if LCD_DEBUG
|
|||
|
LCD lcd1;
|
|||
|
//#endif
|
|||
|
|
|||
|
void dcf77::start_capture()
|
|||
|
{
|
|||
|
DDRB |= 1<<PINB5;
|
|||
|
timer1_init();
|
|||
|
dcf77_flag_start = 0;
|
|||
|
DDRD &= ~(1<<PIND2); //PIND2 en entr<74>e
|
|||
|
EICRA = 1<<ISC00; //Interuption a chaque changement d'<27>tat de INT0
|
|||
|
EIMSK |= 1<<INT0; //Activation de l'interuption INT0
|
|||
|
sei(); //Activation des interuption en g<>n<EFBFBD>rale
|
|||
|
}
|
|||
|
void dcf77::stop_capture()
|
|||
|
{
|
|||
|
EIMSK &= ~(1<<INT0); //D<>sactive l'interuption
|
|||
|
dcf77_flag_start = 0;
|
|||
|
dcf77_bit_count = 0;
|
|||
|
cli();
|
|||
|
}
|
|||
|
void dcf77::hi()
|
|||
|
{
|
|||
|
|
|||
|
time_check = millis() - time_low_dcf77;
|
|||
|
if( time_check >= temps_bas_min || time_low_dcf77 == 0)
|
|||
|
{
|
|||
|
PORTB |= 1<<PINB5; //Led de Debug <20> 1
|
|||
|
parasite_flag = false;
|
|||
|
time_high_dcf77 = millis(); //D<>marage du comptage du temps haut
|
|||
|
time_low_dcf77 = millis() - time_low_dcf77; //Calcul du Temps bas
|
|||
|
if(dcf77_flag_start && dcf77_bit_count <= 58) //D<>marage de la d<>modulation si toute les condition sont OK
|
|||
|
{
|
|||
|
dcf77_status = decodage_en_cours; //En cours de d<>codage
|
|||
|
int bit;
|
|||
|
if(time_low_dcf77 >= time_low_dcf77_min_0 && time_low_dcf77 <= time_low_dcf77_max_0) //Si le temp bas est <= 100ms le bit est <20> 0
|
|||
|
bit = 0;
|
|||
|
else if(time_low_dcf77 >= time_low_dcf77_min_1 && time_low_dcf77 <= time_low_dcf77_max_1) //Si le temp bas est <= 200ms le bit est <20> 1
|
|||
|
bit = 1;
|
|||
|
else //ereur
|
|||
|
{
|
|||
|
//dcf77_bit_count = 0;
|
|||
|
//dcf77_flag_start = 0;
|
|||
|
//return;
|
|||
|
}
|
|||
|
if(dcf77::decode(bit))
|
|||
|
{
|
|||
|
dcf77_bit_count = 0;
|
|||
|
dcf77_flag_start = 0;
|
|||
|
//return;
|
|||
|
}
|
|||
|
dcf77_bit_count++;
|
|||
|
}
|
|||
|
else if(dcf77_bit_count > 58)//Apr<70>s le d<>codage 60e bit
|
|||
|
{
|
|||
|
//atc_.stop_capture(); //Ar<41>t de la capture
|
|||
|
dcf77_flag_start = 0; //Remise a zero du drapeau de d<>marage
|
|||
|
dcf77_bit_count = 0; //Mise <20> zero le nombre de bit decod<6F>
|
|||
|
dcf77_status = decodage_effectuer;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// lcd1.set_cursor(5, 1);
|
|||
|
// lcd1.print_text("Wt S.F.");
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
parasite_flag = true;
|
|||
|
}
|
|||
|
void dcf77::lo()
|
|||
|
{
|
|||
|
|
|||
|
time_check = millis() - time_high_dcf77;
|
|||
|
if( time_check >= temps_haut_min || time_high_dcf77 == 0)
|
|||
|
{
|
|||
|
PORTB &= ~(1<<PINB5);//Led de debug <20> 0
|
|||
|
parasite_flag = false;
|
|||
|
time_high_dcf77 = millis() - time_high_dcf77; //Calcul du temps Haut
|
|||
|
time_low_dcf77 = millis(); //D<>marage du comptage du temps bas
|
|||
|
if(time_high_dcf77 > time_no_modulation | dcf77_flag_start) //Si le Temps bas est > <20> 800, d<>but de la transmition
|
|||
|
{
|
|||
|
dcf77_flag_start = 1;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
dcf77_status = en_attente_de_signal;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
parasite_flag = true;
|
|||
|
}
|
|||
|
bool dcf77::decode(uint8_t bit)
|
|||
|
{
|
|||
|
bool flag_no_error = true;
|
|||
|
if(bit_dcode_n == 0 && !bit) //Bit 00 Toujours <20> 0 si le contraire erreur
|
|||
|
flag_no_error = false;
|
|||
|
else if(bit_dcode_n >= 1 && bit_dcode_n <= 19); //Bits 01 <20> 19 ne nous interesse pas
|
|||
|
else if (bit_dcode_n == 20 && !bit) //Bit 20 Toujours <20> 1
|
|||
|
flag_no_error = false;
|
|||
|
else if (bit_dcode_n >= 21 && bit_dcode_n <= 27) //Bit 21 <20> 27 = Minute
|
|||
|
{
|
|||
|
if(bit)
|
|||
|
dcf77_Minute |= 1 << (bit_dcode_n-21);
|
|||
|
else
|
|||
|
dcf77_Minute &= ~(1 << (bit_dcode_n-21));
|
|||
|
}
|
|||
|
else if(bit_dcode_n == 28 && (dcf77_Minute&0x01) && !bit || bit_dcode_n == 28 && !(dcf77_Minute&0x01) && bit) //Bit de parit<69> des minutes
|
|||
|
flag_no_error = false;
|
|||
|
else if(bit_dcode_n >= 29 && bit_dcode_n <= 34) //Bit 29 <20> 34 = Heure
|
|||
|
{
|
|||
|
if(bit)
|
|||
|
dcf77_Heur |= 1 << (bit_dcode_n-29);
|
|||
|
else
|
|||
|
dcf77_Heur &= ~(1 << (bit_dcode_n-29));
|
|||
|
}
|
|||
|
else if(bit_dcode_n == 35 && (dcf77_Heur&0x01) && !bit || bit_dcode_n == 35 && !(dcf77_Heur&0x01) && bit) //Bit de parit<69> des Heure
|
|||
|
flag_no_error = false;
|
|||
|
else if(bit_dcode_n >= 36 && bit_dcode_n <= 41) //Bit 36 <20> 41 = Jours du moi
|
|||
|
{
|
|||
|
if(bit)
|
|||
|
dcf77_Daymonth |= 1 << (bit_dcode_n-36);
|
|||
|
else
|
|||
|
dcf77_Daymonth &= ~(1 << (bit_dcode_n-36));
|
|||
|
}
|
|||
|
else if(bit_dcode_n >= 42 && bit_dcode_n <= 44); //Bit 42 <20> 44 = Jours de la semaine, ne nous interesse pas
|
|||
|
else if(bit_dcode_n >= 45 && bit_dcode_n <= 49) //Bit 45 <20> 49 = Mois
|
|||
|
{
|
|||
|
if(bit)
|
|||
|
dcf77_Month |= 1 << (bit_dcode_n-45);
|
|||
|
else
|
|||
|
dcf77_Month &= ~(1 << (bit_dcode_n-45));
|
|||
|
}
|
|||
|
else if(bit_dcode_n>= 50 && bit_dcode_n <= 57) //Bit 50 <20> 57 = Ann<6E>e
|
|||
|
{
|
|||
|
if(bit)
|
|||
|
dcf77_Year |= 1 << (bit_dcode_n-50);
|
|||
|
else
|
|||
|
dcf77_Year &= ~(1 << (bit_dcode_n-50));
|
|||
|
}
|
|||
|
else if(bit_dcode_n == 58 && (dcf77_Month&0x01) && !bit || bit_dcode_n && !(dcf77_Month&0x01) && bit);//Parity
|
|||
|
bit_dcode_n++;
|
|||
|
return flag_no_error;
|
|||
|
}
|
|||
|
int dcf77::status()
|
|||
|
{
|
|||
|
return dcf77_status;
|
|||
|
}
|
|||
|
uint8_t dcf77::minutes()
|
|||
|
{
|
|||
|
return dcf77_Minute;
|
|||
|
}
|
|||
|
uint8_t dcf77::heure()
|
|||
|
{
|
|||
|
return dcf77_Heur;
|
|||
|
}
|
|||
|
uint8_t dcf77::month()
|
|||
|
{
|
|||
|
return dcf77_Month;
|
|||
|
}
|
|||
|
uint8_t dcf77::day_month()
|
|||
|
{
|
|||
|
return dcf77_Daymonth;
|
|||
|
}
|
|||
|
uint8_t dcf77::year()
|
|||
|
{
|
|||
|
return dcf77_Year;
|
|||
|
}
|
|||
|
ISR(INT0_vect)//Vecteur d'interuption INT0
|
|||
|
{
|
|||
|
ATOMIC_BLOCK(ATOMIC_FORCEON)
|
|||
|
{
|
|||
|
if(((PIND&(1<<PIND2))>>PIND2))//Si c'est au niveau haut
|
|||
|
{
|
|||
|
atc_.hi();
|
|||
|
}
|
|||
|
else //Passage au niveau bas
|
|||
|
{
|
|||
|
atc_.lo();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|