DCT77 nachbauen

Oct 29, 2004 24 Replies

snipped-for-privacy@tfh-berlin.de (Florian Toulouse) schrieb:

Es geht auch ohne Elektroniklabor. Ein Programmiergerät reicht aus. Manche uC benötigen noch nicht mal das!

Würde mich auch interessieren.

Gruß Jürgen

Mailadress: klein AT ek-p DOT de Advertisement to this mail address is prohibited! MyEbay: http://members.ebay.de/aboutme/do1pjk/

Hallo ,

da es evtl. noch mehr Leute interessiert sende ich Euch mal den gesamten Quellcode. Ich hoffe damit nicht den sonst üblichen USENET Rahmen zu sprengen.

Wer Fragen hat postet Sie..:-)!

Das file enthält die Displaysteuerungen und vorallem viele Zeilen, in denen einfach die Buchstaben, Zahlen etc. ausgegeben werden. Entscheidend ist, wie das Signal am Eingang des uc80517A quasi abgestatet wird: Mittels eines internen Zählers wird die Amplitudenabsenkung vermessen und so eine 0 oder 1 registriert. mit einem guten Compiler ansehen, dann wird es übersichtlicher..!

flo

/* ----------------------------------------------------------------- Modulname: DCF-clock1.c Datum: 28.05.04 Autor: Flo et flo Version: 0.1

Beschreibung: ---------------------------------------------------------------*/

#include #include #include #include

int i; data unsigned char z = 0; data unsigned char y = 0; data unsigned char x = 0; data unsigned int sec = 0; data unsigned char min = 0; data unsigned char hour = 0; data unsigned char tag= 0; data unsigned char wochentag= 0; data unsigned char wochentag_string[2]; data unsigned char monat= 0; data unsigned char jahr= 0; data unsigned char signal[60] = 0; // bitadressable array data unsigned int tmp = 5; data char data_complete = 0; bit null = 0; int diff; unsigned int a =0; xdata unsigned char LCD_KReg_W _at_ 0xf680; // Kontrollregister schreiben xdata unsigned char LCD_DReg_W _at_ 0xf681; // Datenregister schreiben xdata unsigned char LCD_KReg_R _at_ 0xf682; // Kontrollregister lesen xdata unsigned char LCD_DReg_R _at_ 0xf683; // Datenregister lesen data unsigned char min_1stelle; data unsigned char min_2stelle; data unsigned char hour_1stelle; data unsigned char hour_2stelle; data unsigned char sec_1stelle; data unsigned char sec_2stelle; data unsigned char tag_1stelle; data unsigned char tag_2stelle; data unsigned char monat_string[3]; // ------------- functions ----------------------------------

void wait(unsigned int p) { unsigned int t; for (t = p; t > 0; t--); }

void convert_time()

{ // konvertieren der min in ASCII kode char tmp1=0; char tmp2=0; tmp1= min; //2.dec.stelle tmp2=min/10; min_2stelle =min - tmp2*10; // 1.dec.Stelle min_1stelle= tmp1/10;

// ascii +48 ='0' min_1stelle+=48; min_2stelle+=48;

//*** STUNDE konvertieren tmp1=hour; //2.dec.stelle tmp2=hour/10; hour_2stelle =hour - tmp2*10; // 1.dec.Stelle hour_1stelle= tmp1/10;

// ascii +48 ='0' hour_1stelle+=48; hour_2stelle+=48;

// *** sekunde ascii konvertieren

tmp1=sec; //2.dec.stelle tmp2=sec/10; sec_2stelle =sec - tmp2*10; // 1.dec.Stelle sec_1stelle= tmp1/10;

// ascii +48 ='0' sec_1stelle+=48; sec_2stelle+=48;

// *** Tag ascii konvertieren

tmp1=tag; //2.dec.stelle tmp2=tag/10; tag_2stelle =tag - tmp2*10; // 1.dec.Stelle tag_1stelle= tmp1/10;

// ascii +48 ='0' tag_1stelle+=48; tag_2stelle+=48;

}

konvert_wochentag() { switch(wochentag) { case 1: wochentag_string[0]='M'; wochentag_string[1]='o';//strcpy(wochentag_string, "Mo"); break;

case 2: wochentag_string[0]='D'; wochentag_string[1]='i'; break;

case 3: wochentag_string[0]='M'; wochentag_string[1]='i'; break;

case 4: wochentag_string[0]='D'; wochentag_string[1]='o'; break;

case 5: wochentag_string[0]='F'; wochentag_string[1]='r'; break;

case 6: wochentag_string[0]='S'; wochentag_string[1]='a'; break;

case 7: wochentag_string[0]='S'; wochentag_string[1]='o'; break; } }

konvert_monat() { switch(monat) { case 1: monat_string[0]='J'; monat_string[1]='a'; monat_string[2]='n'; break;

case 2: monat_string[0]='F'; monat_string[1]='e'; monat_string[2]='b'; break;

case 3: monat_string[0]='M'; monat_string[1]='ä'; monat_string[2]='r'; break;

case 4: monat_string[0]='A'; monat_string[1]='p'; monat_string[2]='r'; break;

case 5: monat_string[0]='M'; monat_string[1]='a'; monat_string[2]='i'; break;

case 6: monat_string[0]='J'; monat_string[1]='u'; monat_string[2]='n'; break; case 7: monat_string[0]='J'; monat_string[1]='u'; monat_string[2]='l'; break;

case 8: monat_string[0]='A'; monat_string[1]='u'; monat_string[2]='g'; break; case 9: monat_string[0]='S'; monat_string[1]='e'; monat_string[2]='p'; break; case 10: monat_string[0]='O'; monat_string[1]='k'; monat_string[2]='t'; break; case 11: monat_string[0]='N'; monat_string[1]='o'; monat_string[2]='v'; break; case 12: monat_string[0]='D'; monat_string[1]='e'; monat_string[2]='z'; break; } }

ausgabe_datum() {

LCD_DReg_W = wochentag_string[0]; LCD_KReg_W = 0xcc; // wochentag : Mo, Di... wait(4); LCD_DReg_W = wochentag_string[1]; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = ' '; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = tag_1stelle; LCD_KReg_W = 0xcc; // 01, 02. 3 .... TAG wait(4); LCD_DReg_W = tag_2stelle; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = '.'; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = monat_string[0]; LCD_KReg_W = 0xcc; // Monat : Jan, Feb... wait(4); LCD_DReg_W = monat_string[1]; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = monat_string[2]; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = '.'; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = '2'; LCD_KReg_W = 0xcc; // Das JAhr fängt bei uns immer mit 200 an wait(4); LCD_DReg_W = '0'; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = '0'; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = jahr+48; LCD_KReg_W = 0xcc; // Das aktuelle Jahr als Ascii Code als +

48 wait(4); }

ausgabe_zeit() {

LCD_DReg_W = ' '; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = ' '; LCD_KReg_W = 0xcc; // anzeige wait(4);

LCD_DReg_W = hour_1stelle; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = hour_2stelle; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = ':'; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = min_1stelle; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = min_2stelle; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = ':'; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = sec_1stelle; LCD_KReg_W = 0xcc; // anzeige wait(4); LCD_DReg_W = sec_2stelle; LCD_KReg_W = 0xcc; // anzeige wait(4);

}

void printsynch() { LCD_KReg_W = 0xc3; wait(4); LCD_DReg_W = 's'; wait(4); LCD_DReg_W = 'y'; wait(4); LCD_DReg_W = 'n'; wait(4); LCD_DReg_W = 'c'; wait(4); LCD_DReg_W = 'h'; wait(4); }

void init_capcom(){ // init. capture-compare-unit CCEN=0; CCEN |=0x40;// setzt den Cap Comp, benutzt das register CC3 und den Pin P1.3 reagiert nur auf steigende flanke

CC4EN &=0xF9; CC4EN |=0x02; // setzt Modus fuer CC4 benutzt den pin 1.4

T2PS=1; // Setup counter clock fosz/96 CTCON &=0x3F; CTCON |=0x80; // Setup counter clock fosz/96

I2FR=0; // Input fuer CC4 reagiert auf fallende Flanke IEX2 //I3FR=0; // Input fuer CRC reagiert auf steigende Flanke IEX3 //T2CM = 0;

T2R1=1; T2R0=0; // reload enabled

CRC=0x1e8c; //setzt den timer auf einen takt von 0.501 sekunden mit

2^ 16 - .501 *fosz/96 ; fosz =11.0592mhz

TF2= 0 ; // erase timer flag;

T2I1=0; T2I0=1; // starts timer;

}

void init_ser0() { // init. serielle IO #0

BD =1; //setup Baudgenerator

S0CON=0x52; // enable 8-bit UART, receiver enabled PCON |=0x80; // set divider to 2^1

S0RELL=0xee; S0RELH=0x03; // Baudrate 19200 bit/s

}

void init_LCD() { wait(1500); LCD_KReg_W = 0x38; wait(410); LCD_KReg_W = 0x38; wait(10); LCD_KReg_W = 0x38; wait(4);

LCD_KReg_W = 0x38; wait(4); LCD_KReg_W = 0x06; wait(4); LCD_KReg_W = 0x0c; wait(4); LCD_KReg_W = 0x01; // clear display wait(164); LCD_KReg_W = 0x80; // adresse für cursor -> anfang erste zeile wait(4); } void init_T0(){ // init. Timer 0 for sec-clock TMOD &= 0x80; TMOD |= 0x01; // T0 = 16bit timer TF0 = 0; }

int capcom_result() { diff = CC4 - CC3; //differenz zw. abst. u. aufst. flanke : CC4 (abst.)-CC3 (aufst.) if (diff *-1 = 60) { // min und stundenumschaltung sec = 0; min++; if (min == 60) { min = 0; hour++; if (hour == 24) { hour = 0; } } } }

int aufendederminutewarten() // gibt eine 1 wenn ende der sekunde erkannt, sonst null { IEX2=0; while(!TF2) ; //warten auf Überlauf timer 2, nach 0,501 s TF2=0; while(!TF2); // der timer 2 läuft zum zweiten mal über, nach ca. 1.02 sek, in der Zeit muss TF2=0; // mindestens einmal das IEX2 oder IEX6 flag gesetzt worden sein!! // hier evtl. noch einen delay einbauen , falls das Interruptflag noch nicht gesetzt ist bei 1.02 s if(IEX2) return 0; else return 1; } void bienvenue() { LCD_DReg_W = ' '; LCD_KReg_W = 0xcc; // verschieben des cursors wait(4); LCD_DReg_W = ' '; LCD_KReg_W = 0xcc; // wait(4);

LCD_DReg_W = ' '; LCD_KReg_W = 0xcc; // wait(4); LCD_DReg_W = 'f'; LCD_KReg_W = 0xcc; // wait(4); LCD_DReg_W = 'l'; LCD_KReg_W = 0xcc; // wait(4); LCD_DReg_W = 'o'; LCD_KReg_W = 0xcc; // 1 wait(4); LCD_DReg_W = 'p'; LCD_KReg_W = 0xcc; // 1 wait(4); LCD_DReg_W = ' '; LCD_KReg_W = 0xcc; // wait(4); LCD_DReg_W = 'f'; LCD_KReg_W = 0xcc; // e wait(4); LCD_DReg_W = 'u'; LCD_KReg_W = 0xcc; // 1ge wait(4); LCD_DReg_W = 'n'; LCD_KReg_W = 0xcc; // 1e wait(4); LCD_DReg_W = 'k'; LCD_KReg_W = 0xcc; // wait(4);

} // ------------- main ----------------------------------

void main() { TR0=1; // startet timer0 der nur für die display init gebraucht wird init_ser0(); // initialisieren der seriellen schnittstelle init_capcom(); // " der Capture Compare Unit init_T0(); // " des timers 0 nur für display TF0=0; init_LCD(); IEX6 = 0; IEX2 = 0; // um auf die erste fallende flanke zu warten muss das flag zurückgesetzt werden printf("hallo\n");

bienvenue(); // gi while(!IEX2) ; IEX2=0; TF2=0; while(!TF2); TF2=0; //**** das proggi beginnt **** while(1) { //endlosschleife beginnt CRC=0x1e8c; //setzt den timer auf einen takt von 0.501 sekunden mit

2^ 16 - .501 *fosz/96 IEX2=0; while(!IEX2) ; //auf erste abfallende flanke warten! IEX2=0; TF2=0; //T2=0; //timer zurücksetzen, ab jetzt ist der abtasttakt synchronisiert, FUNZT NICHT!! // **** die synchronisierphase beginnt **** while(!TF2) ; TF2=0; while(!aufendederminutewarten()) ; // diese funktion wartet nur auf das ende der minute,// es werden keine anderen aktionen ausgeführt, auch keine interrupts bedient,

printf("signal gefunden, daten werden gelesen \n"); while(!aufendederminutewarten()) { signal[sec]=capcom_result(); printf("synchronisieren \n"); //printsynch(); // gibt auf dem display "synch" aus; sec++; } printf(" signal gelesen , daten werden dekodiert! \n"); // if (parity_min) // { decode(); // dekodiert und schreibt in sec,min,hour funktioniert.. konvert_wochentag(); // konvertiert den Wochentag und schreibt in das entsprechende Kürzel in das konvert_monat(); // array wochentag_string[] //***** ab hier beginnt der routinelauf: die uhrzeit ist dekodiert und kann den ganzen tag laufen bis 12:12h

while (!( (hour==15 && min ==14 && sec==55) ||(signal[20]&&(hour==15 && min ==30 && sec==55)) ||(!signal[20]&&(hour==2 && min ==1 && sec==55)) ) ) { // endlosschleife fast immer erfüllt, nur um 12:12h wird quasi resettet //printf("capcomresult: %d \n",capcom_result()); CRC=0x1f00; //setzt den timer auf einen takt von 0.500 sekunden mit 2^ 16 - .501 *fosz/96 TF2=0; uhr(); // optional kann man noch in der funktion die while schleife durch eine if anweisung ersetzen // TF2=0; // while(!TF2); printf(" %bu:%bu:%d wochentag:%bu , %bu.%bu.200%bu \n",hour,min,sec,wochentag,tag,monat,jahr); convert_time(); LCD_KReg_W = 0x01; //display clear wait(164);

ausgabe_zeit(); LCD_KReg_W = 0xc0; // adresse für cursor -> anfang erste zeile wait(4);

ausgabe_datum();

} //} } }

Hast recht, nach FORTRAN-III gings nur noch bergab.

mfg Rolf Bombach

Ich kenne es nur mit Jahreszahl-Numerierung. Demnach meinen wir beide das gleiche? NACK. Alles vor und inklusive F77 ist gruslig.

-/R'Hollerith-Datentypen oder wie die Dinger heißen sollen ja wohl aber endlich abgeschafft werden'J/-

Die Wissenschaft ist der Verstand der Welt, die Kunst ihre Seele. Maxim Gorkij, russischer Schriftsteller (1868 - 1936)

Anekdote am Rande: Ein Kollege kommt zu mir...

Kollege: Du, Georg, du musst mir noch was auf dem PC installieren. Ist aber schlimmer als Tiersex... Ich: (grübel) Fortran? Kollege: Woher weisst du???

Georg Acher, acher@in.tum.de http://wwwbode.in.tum.de/~acher "Oh no, not again !" The bowl of petunias

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required