-
Data: 2019-05-09 10:48:58
Temat: Re: Przykładowe ramki DCF77
Od: Piotr Gałka <p...@c...pl> szukaj wiadomości tego autora
[ pokaż wszystkie nagłówki ]W dniu 2019-05-09 o 08:04, Atlantis pisze:
> Pracuję obecnie nad własną biblioteką do obsługi modułów DCF77
> (częściowo opierając się na kodzie Arduino). Niby działa, jednak od
> czasu do czasu pojawiają się problemu i dekodowany czas różni się od
> poprawnego.
Może Ci się przyda.
Dawno, dawno temu (lata 95..97) zrobiłem odbiornik DCF podłączony pod
COM komputera (zasilanie też z COM). Odbiornik wystawiał sygnał z DCF na
którejś z linii RS232 i z tej linii go czytałem.
Trochę się naszukałem w starych plikach, ale znalazłem. Poniżej źródła.
Zauważyłem, że odwołuję się do doneinfo.h. Poszukałem co to takiego -
jakaś forma linijki pokazującej postęp procesu - nie ma związku z samym DCF.
Nie chce mi się wczytywać w szczegóły. Na pierwszy rzut oka widzę, że:
- RS232 obsługuję po adresach - tak się robiło pod DOS
- do odmierzania czasu używam wysyłania w koło czegoś po RS232
Przy ^C^V program pocztowy pozawijał niektóre linijki.
============================= plik DCF77.H ============================
// dcf77.h
// DCF77 class - odbior sygnalu DCF77 przez port RS232
#ifndef __DCF77_H
#define __DCF77_H
#ifndef __DONEINFO_H
#include "doneinfo.h"
#endif
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
class DCF77
{
DWORD blo; // bufory na zbierane bity
WORD bhi;
int addr; // adres portu
enum {DLL=0, // Divisor Latch Low byte
DLH = 1, // Divisor Latch High byte
IER = 1, // Interrupt Enable Register - zezw. na przerwania
IIR = 2, // Interrupt Identification Register
LCR = 3, // Line Control Register - tryb transmisji
MCR = 4, // Modem Control Register - set innych linii
LSR = 5, // Line Status Register - stan transmisji
MSR = 6}; // Modem Status Register - stan innych linii
int parity(WORD w); // sprawdzenie parzystosci slowa
public:
DCF77(int com); // konstruktor
int read(DoneInfo *d=0); // odbior DCF77 ret:n imp (<0-bledy)
int gettime(struct time *t); // odczytany czas ret:0-ok,1-err
int getdate(struct date* d); // odczytana data ret:0-ok,1-err
};
#endif // __DCF77_H
============================ plik DCF77.CPP ============================
// dcf77.cpp
// DCF77 class - odbior sygnalu DCF77 przez port RS232
#include <dos.h>
#include <conio.h>
#include "dcf77.h"
DCF77::DCF77(int com):blo(0),bhi(0)
{
static int adrt[4]={0x3F8,0x2F8,0x3E8,0x2E8}; // adresy COM-ow
int div=48; // predkosc 2400
int lcr=3; // format 8N1
int mcr=1; // DTR=1
addr=adrt[com];
outportb(addr+LCR,0x80); // Divisor Latch Access
outportb(addr,div&0xFF); // Divisor Latch low byte
outportb(addr+DLH,div>>8); // high byte
outportb(addr+LCR,lcr); // Line Control Register
outportb(addr+MCR,mcr); // Modem Control Register
outportb(addr+IER,0); // Interrupt Enable Register
inportb(addr); // wyczyszczenie bufora
outportb(addr,0); // zapelnienie bufora nadawczego
outportb(addr,0);
}
int DCF77::parity(WORD w)
{
w^=w>>8;w^=w>>4;w^=w>>2;w^=w>>1;
return w&1;
}
// zwraca:
// nb = liczba odebranych impulsow, powinno byc co najmniej 39 impulsow
// -1 = brak impulsow przez 5 sekund
// -2 = nie podlaczony odbiornik - szum zamiast impulsow
// -3 = brak konca
// -4 = klawisz
int DCF77::read(DoneInfo *d) // odbior DCF77
{
int b,b0=0x10,b1=0x10; // 0x10 -> dodatnie zbocze bedzie prawdziwe
int valid=0; // na poczatku pracy
int dn=0; // licznik petli w sekundzie DCF77
int lock=0; // blokowanie analizy linii wejsciowej
int down=0; // bylo ujemne zbocze
int nb=0; // licznik odebranych bitow
int ns=0; // licznik zmian stanu w czasie blokowania
// w jednej sekundzie miesci sie 240 nadan 2400B:8N1
static const
lockT=234, // blokada dla calego okresu (0.975s)
lockt=18, // blokada dla impulsu (0.075s)
lim2s=420, // czas dla znacznika konca (1.75s)
lim01=31, // prog rozroznienia 0/1 (0.13s)
lim5s=1200; // czas dla braku impulsow (5s)
bhi=0; // zeruje bufory wynikowe
blo=0;
if(d)d->limit(60); // po 59 impulsie czeka jeszcze 2s
while(1){
if(inportb(addr+LSR)&0x20){
outportb(addr,0); // teraz mamy troche czasu bez naruszania dn
if(down){ // bylo ujemne zbocze - przetwarzanie i info
blo>>=1;
if(bhi&1L)blo|=0x80000000L; // przeniesienie bitu
bhi>>=1;
if(dn>lim01)bhi|=0x8000; // wpisanie aktualnego bitu
nb++; // liczba odebranych bitow
if(d)d->done(nb); // to moze zajac czas (dlatego down)
down=0; // obsluzone
}
dn++; // licznik wyslanych przez RS232 bajtow w impulsie DCF
if(dn>lim5s)return -1; // brak impulsow
if(nb>60)return -3; // za duzo impulsow
if(kbhit()){getch();return -4;} // nacisniety klawisz
}
b=inportb(addr+MSR)&0x10; // sprawdzenie linii wejsciowej
if(dn>lock){ // tylko gdy nie ma blokady
if(b!=b0){ // zmiana stanu
b0=b; // nowy stan
if(valid){ // juz bylo pierwsze dodatnie zbocze
if(b){ // dodatnie zbocze
if(dn>lim2s)return nb; // koniec minuty (dn>1.75s)
lock=lockt; // blokada do 0.075s
}
else{ // ujemne zbocze
down=1; // flaga ujemnego zbocza
lock=lockT; // blokada do 0.975 s
}
}
if(b){valid=1;dn=0;}// juz bylo dodatnie zbocze i licznik od 0
b1=b;
ns=0;
}
}
if(b!=b1){ // nieoczekiwana zmiana stanu
b1=b;
if(++ns>9)return -2; // szum - nie podlaczony odbiornik
}
}
}
int DCF77::gettime(struct time *t) // odczytany czas ret:0-ok,1-err
{
int h,l;
if((blo&0x200)==0 || // nie ma bitu startu
parity(WORD((blo>>10)&0xFF)) || // parzystosc minut
parity(WORD((blo>>18)&0x7F)) )return 1; // parzystosc godzin
h=int((blo>>14)&7);l=int((blo>>10)&0xF);t->ti_min=h*
10+l;
if(h>5 || l>9)return 1; // zle wartosci dla minut
h=int((blo>>22)&3);l=int((blo>>18)&0xF);t->ti_hour=h
*10+l;
if(h>2 || l>9 || t->ti_hour>23)return 1; // zle wartosci dla godzin
t->ti_sec=0;
t->ti_hund=0;
return 0;
}
int DCF77::getdate(struct date* d) // odczytana data ret:0-ok,1-err
{
int h,l,y;
if((blo&0x200)==0 || // nie ma bitu startu
parity(WORD(blo>>25))^parity(bhi) )return 1;// parzystosc daty
h=int((blo>>29)&3);l=int((blo>>25)&0xF);d->da_day=h*
10+l;
if(l>9 || d->da_day>31)return 1; // zle wartosci dnia
h=(bhi>>6)&1;l=(bhi>>2)&0xF;d->da_mon=h*10+l;
if(l>9 || d->da_mon>12)return 1; // zle wartosci miesiaca
h=(bhi>>11)&0xF;l=(bhi>>7)&0xF;y=h*10+l;
if(h>9 || l>9)return 1;
d->da_year=(y<98)?2000+y:1900+y; // prawidlowo do 2097 roku
return 0;
}
Następne wpisy z tego wątku
- 09.05.19 10:53 Piotr Gałka
- 09.05.19 12:36 Atlantis
- 09.05.19 12:40 Cezar
- 09.05.19 12:49 Cezar
- 11.05.19 00:27 Atlantis
- 06.06.19 12:14 robot
Najnowsze wątki z tej grupy
- Dlaczego energia elektryczna jest droga i cały czas drożeje
- twardy dysk stuka
- Oclenie alkalicznych akumulatorów
- Powerbank jednonapieciowy, a trzynapieciowy
- Lustra w maszynie ASML
- DC blocker i buczące toroidy
- Problemy TSMC cd
- Detektor
- Może tutaj się uda: [NTG] Elewacja / dziurawa Churka
- Falownik jednofazowy a żarówka
- Agregat i "legalność" instalacji
- Uziom
- (Ponownie) odkryto, że ładowanie pulsacyjne robi dobrze
- driver led ?
- Długość wtyku zasilającego ?5.5mm
Najnowsze wątki
- 2024-05-03 Warszawa => Sprzedawca usług rekrutacyjnych <=
- 2024-05-03 Warszawa => Mid/Senior QA Engineer <=
- 2024-05-03 Warszawa => Mid/Senior QA Engineer <=
- 2024-05-03 Warszawa => Senior PHP Developer (Symfony) <=
- 2024-05-03 Rzeszów => UX/UI Designer <=
- 2024-05-03 Giertych przetarł szlak: byli członkowie zarządu Orlenu śledztwa prokuratorskie obserwują z zagranicy
- 2024-05-03 Warszawa => Senior Rust Software Engineer <=
- 2024-05-03 Kraków => UX/UI Designer <=
- 2024-05-03 Warszawa => International freight forwarder <=
- 2024-05-02 Silnik Stirlinga - energia mechaniczna wytwarzana z ciepła bez dostarczania paliwa!
- 2024-05-02 Kraków => Senior .Net Programmer <=
- 2024-05-02 Sprowadzenie pożaru zagrażającego mieniu w wielkich rozmiarch
- 2024-05-02 Zielona Góra => Spedytor międzynarodowy <=
- 2024-05-02 Katowice => Performance Analyst <=
- 2024-05-02 Gdańsk => Full Stack web developer (obszar .Net Core, Angular6+) <=