// funkce pro cteni DCF prijimace byte Prijem(void) // prijem znaku z linky { TH0=256-12; // casovy dohled 10 ms pri 3,68 MHz, 12x256 stroj. cyklu, casovac T0 H TF0=0; // vynulovani preteceni casovace T0 do { if(RI) // priznak prijateho znaku z linky { RI=0; return(SBUF); // prijaty znak z buferu seriove linky } if(TF0) // doslo k preteceni casovace - casovy dohled 10 ms { // u protokolu Meinberg se na 1. znak ceka az 2 vteriny, potom // jsou mezery mezi znaky max. 4 ms TF0=0; Overtime=1; // indikace prekroceni 10 ms return(0); } } while(1); } byte Prijempol(void) // prijem polozky { byte i; i=Prijem(); // desitky i-=0x30; i*=10; i+=Prijem()-0x30; // jednotky Prijem(); // oddelovaci znak - nevyhodnocuje se return(i); } void Prijemnz(byte j) // prijem nazvu polozky { // nazev polozky, musi byt pismeno if(j!=Prijem()) { if(Pocetchyb<255) Pocetchyb++; } if(':'!=Prijem()) { if(Pocetchyb<255) Pocetchyb++; } } // ................................................................................. // funkce pro cteni s CRC byte Prijempol1(void) // prijem polozky s kontrolnim souctem { byte i, j; i=Prijem(); Crc+=i; // desitky i-=0x30; i*=10; j=Prijem(); Crc+=j; // jednotky i+=j-0x30; Crc+=Prijem(); // oddelovaci znak return(i); } void Prijemnz1(byte j) // prijem nazvu polozky s kontrolnim souctem { byte i; i=Prijem(); Crc+=i; // nazev polozky, musi byt pismeno if(i!=j) { if(Pocetchyb<255) Pocetchyb++; } i=Prijem(); Crc+=i; if(i!=':') { if(Pocetchyb<255) Pocetchyb++; } } /* -------------- protokol Meinberg -----------------------*/ void Meinb(void) { byte i,j; // Jednosmerny protokol, pouze se prijima retezec vysilany DCF prijimacem. // Program pise na 2 radkovy displej datum a cas. Pise se do buferu displeje, // zobrazeni se provadi dodatecne. // Pro spusteni protokolu Meinberg musi byt u prijimace DCF-S1 RXD na nule. // U prijimace DCF-S, ktery si z RXD bere zaporne napajeni (bily drat na RXD, // zaporna polarita je na datech u RS232 logicka jednicka), se protokol // prepina prepojenim zluteho dratu (RXD prijimace) v konektoru // na + (RTS a CTS). // Data z prijimace se zapisuji do displejoveho buferu // v poradi jak prijdou: den v mesici, mesic, rok, // den v tydnu, hodina, minuta, vterina. Pro roztrideni dat staci pouze // pocitat bajty od startovaciho znaku, program kontroluje i spravnost // textovych identifikatoru a oddelovacich znaku. Data se z textoveho tvaru // prevadi na binarni cisla. // Cas se prenasi jednou za dve vteriny. if(Menu==2) TXD=0; // DCF-S1 else TXD=1; // DCF-S, Menu=1 j=200; // cekani na 1. znak omezeno na 2 vteriny, prenos casu jednou za 2 s RI=0; do { Overtime=0; i=Prijem(); j--; if(!j) return; // >2 s; prijimac nepripojeny, nebo dosud nezasynchronizovany. } while(Overtime); // Overtime na 1 pri prekroceni 10 ms if(i!=0x02) return; // cekani na 02, zacatek retezce // Data z prijimace se zapisuji do displejoveho buferu v textovem // tvaru v poradi jak prijdou: den v mesici, mesic, rok, // den v tydnu, hodina, minuta, vterina. RI=0; Overtime=0; // hlidani casu <10 ms mezi prijatymi znaky Prijemnz('D'); // prijem nazvu D: datum // nazev se pouze kontroluje, pri neshode se pricte Pocetchyb Den=(Prijempol()); // prijem polozky Den - dvoumistne cislo 0 - 99 Mesic=(Prijempol()); // mesic Rok=(Prijempol()); // rok Prijemnz('T'); // prijem nazvu T: den v tydnu, pouze pro kontrolu Den_v_tydnu=(Prijem()-0x30); // '1' az '7' (0x31 az 0x37) = Po az Ne: i=Prijem(); // prijem oddelovaciho znaku ';' if(i!=';') { if(Pocetchyb<255) Pocetchyb++; } Prijemnz('U'); // prijem nazvu U: cas Hod=(Prijempol()); // hodina Min=(Prijempol()); // minuta Sec=(Prijempol()); // vterina Prijem(); // indikace ze k synchronizaci doslo po resetu (vzdy ' ') nekontroluje se Sync=Prijem(); // indikace synchronizace, 0x2A=aut. chod 0x20=synchronizace Let_zim=Prijem(); // indikace zimniho/letniho casu: 0x20=zimni cas 'S'=letni cas Ind_zmen=Prijem(); // indikace zmeny casu: // 0x41; v pristi hodine bude prestupna vterina // 0x21; v pristi hodine bude zmena casu // 0x20; nebude nic i=Prijem(); // ukoncovaci znak retezce 0x03 if(i!=0x03) { if(Pocetchyb<255) Pocetchyb++; } if(Overtime) { if(Pocetchyb<255) Pocetchyb++; } // prekroceni casu mezi znaky Pridata=1; // priznak ze byla prijata data } /* --------- prijem spec. protokolu (Meinberg s kontrolnim souctem) -------*/ void Spec(void) { byte i; byte Pocetzn; TXD=1; RI=0; Overtime=0; Prijem(); // pokud se do 10 ms neprijme znak, nastavi se Overtime if(!Overtime) return; // test klidu na lince 10 ms pred 1. znakem // protokol ma na konci pridany binarni kontrolni soucet, ktery // by mohl byt zamenen se znakem STX. Proto test klidu na lince. i=100; // cekani na 1. znak max. 1 vterinu, cas se prenasi kazdou vterinu do { Overtime=0; Prijem(); i--; if(!i) return; // prijimac nepripojeny, nebo jeste nema platny cas } while(Overtime); i=SBUF; // posledni prijaty znak v SBUF zustal if(i!=0x02) // test na zacatek, STX { if(Pocetchyb<255) Pocetchyb++; return; } Overtime=0; // hlidani casu <10 ms mezi prijatymi znaky RI=0; Crc=2; // prvni prijaty znak byl STX, 0x02 Prijemnz1('D'); //kontrola nazvu, D= datum Den=(Prijempol1()); // den-vypis dvoumistneho cisla 0 - 99 Mes=(Prijempol1()); // mesic Rok=(Prijempol1()); // rok Prijemnz1('T'); // kontrola nazvu T= den v tydnu Den_v_tydnu=Prijem(); Crc+=i; // den v tydnu // '1' az '7' (0x31 az 0x37), Po az Ne: i=Prijem(); Crc+=i; // oddelovac ';' if(i!=';') { if(Pocetchyb<255) Pocetchyb++; } Prijemnz1('U'); // kontrola nazvu U= cas Hod=(Prijempol1()); // hodina Min=(Prijempol1()); // minuta Sec=(Prijempol1()); // vterina Crc+=Prijem(); // indikace ze k synchronizaci doslo po resetu (vzdy ' ') Sync=Prijem(); Crc+=Sync; // indikace synchronizace, 0x2A aut. chod, 0x20 synchronizace Let_zim=Prijem(); Crc+=Let_zim; indikace zimniho/letniho casu: 0x20=zimni cas 'S'=letni cas Ind_zmen=Prijem(); Crc+=Ind_zmen // indikace zmeny casu: // 0x41; v pristi hodine bude prestupna vterina // 0x21; v pristi hodine bude zmena casu // 0x20; nebude nic i=Prijem(); Crc+=i; // ukoncovaci znak retezce 0x03 if(i!=0x03) { if(Pocetchyb<255) Pocetchyb++; } Crc+=Prijem(); // kontrolni soucet za znakem 0x03 // vyhodnoceni kontrolniho souctu, musi vyjit nula if(Crc) { if(Pocetchyb<255) Pocetchyb++; } if(Overtime) { if(Pocetchyb<255) Pocetchyb++; } // prekroceni casu 10 ms mezi znaky }