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ée
|
|
EICRA = 1<<ISC00; //Interuption a chaque changement d'état de INT0
|
|
EIMSK |= 1<<INT0; //Activation de l'interuption INT0
|
|
sei(); //Activation des interuption en géné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 à 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 à 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 à 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ès le décodage 60e bit
|
|
{
|
|
//atc_.stop_capture(); //Arêt de la capture
|
|
dcf77_flag_start = 0; //Remise a zero du drapeau de démarage
|
|
dcf77_bit_count = 0; //Mise à zero le nombre de bit decodé
|
|
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 à 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 > à 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 à 0 si le contraire erreur
|
|
flag_no_error = false;
|
|
else if(bit_dcode_n >= 1 && bit_dcode_n <= 19); //Bits 01 à 19 ne nous interesse pas
|
|
else if (bit_dcode_n == 20 && !bit) //Bit 20 Toujours à 1
|
|
flag_no_error = false;
|
|
else if (bit_dcode_n >= 21 && bit_dcode_n <= 27) //Bit 21 à 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é des minutes
|
|
flag_no_error = false;
|
|
else if(bit_dcode_n >= 29 && bit_dcode_n <= 34) //Bit 29 à 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é des Heure
|
|
flag_no_error = false;
|
|
else if(bit_dcode_n >= 36 && bit_dcode_n <= 41) //Bit 36 à 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 à 44 = Jours de la semaine, ne nous interesse pas
|
|
else if(bit_dcode_n >= 45 && bit_dcode_n <= 49) //Bit 45 à 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 à 57 = Anné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();
|
|
}
|
|
}
|
|
} |