;**************************************************************** ;* Name : klokschool.asm * ;* Author : Bert De Deckere * ;* Notice : Copyright Bert (c) 2009 * ;* : All Rights Reserved * ;* Date : 29/10/2009 * ;* Version : 1.0 * ;* Notes : Please make sure you use the appropriate µC * ;* : * ;**************************************************************** #include P18F1320.inc ; PIC18F1320: +------v------+ ; signal in <[RA.0 RB.3]> segment d ; display 1 <[RA.1 RB.2]> segment e ; display 4 <[RA.4 RA.7]> kristal ; MCLR <[RA.5 RA.6]> kristal ; GND <[ ]> V+ ; display 2 <[RA.2 RB.7]> dubbele punt ; display 3 <[RA.3 RB.6]> segment a ; segment b <[RB.0 RB.5]> segment f ; segment c <[RB.1 RB.4]> segment g ; +-------------+ CONFIG PWRT = ON ; Enable power up timer CONFIG FSCM = ON ; Fail-Safe Clock Monitor enabled CONFIG WDT = OFF ; disable watchdog timer CONFIG MCLRE = OFF ; Master CLear Reset pin disabled, RA5 input pin enabled CONFIG DEBUG = OFF ; Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins CONFIG LVP = OFF ; Low-Voltage programming disabled (necessary for debugging) CONFIG OSC = INTIO2 ; High speed oscillator CONFIG IESO = ON ; Oscillator Switchover mode disabled CONFIG BOR = ON ; Brown-out reset enabled #define signaal PORTA, 0 ; signaalingang ;het DCF-77 signaal wordt gezien als corrigeersignaal niet als kloksignaal ;vandaar dubbele variabelen voor tijd en datum ;variabele lengte wordt gecodeerd op volgende manier ;bit7 : signaal is weggevallen ;bit6 : deze onthoud dat "decodeer" net nog verhoogd is ;bit5 : onthoudt dat hij net naar "nul" geweest is ;bit4 : pariteitsbit voor datum laag equ 00h ; variabele die telt hoe lang het signaal laag is van het DCF-77 signaal hoog equ 01h ; variabele die telt hoe lang het signaal hoog is van het DCF-77 signaal lengte equ 02h ; variabele die de overgang bijhoudt van het signaal, waarna de signaallengte opgenomen wordt decodeer equ 03h ; variabele die onthoudt welke bit waar moet komen van het DCF-77 signaal uur equ 04h ; variabelen voor tijd en datum min equ 05h sec equ 06h dag equ 07h maand equ 08h uur2 equ 09h ; rechter nibble van "uur" min2 equ 0Ah ; rechter nibble van "min" sec2 equ 0Bh dag2 equ 0Ch ; rechter nibble van "dag" maand2 equ 0Dh ; rechter nibble van "maand" wvar equ 0Eh ; hier wordt het werkregister in bewaard gedurende de timer interrupt tempcmd equ 10h ; deze zorgt ervoor dat er naar de juiste variabele geschreven wordt pariteit equ 11h ; hier worden de bits samengeteld voor de pariteitscontrole weekdag equ 12h jaar equ 13h teller equ 14h ; deze verzorgt de tijdbasis voor de seconde tijddat equ 15h ; onthoud de overgang tussen tijd naar datum display equ 16h ; omwille van de BCD-code wordt eerst de linker nibble op display gezet, daarna rechter nibble teller2 equ 17h ; deze onthoud welk display aangestuurd moet worden maand3 equ 18h ; linker nibble van "maand" status_temp equ 19h ; variabele om registers te herstellen dag3 equ 1Ah ; linker nibble van "dag" min3 equ 1Bh ; linker nibble van "min" uur3 equ 1Ch ; linker nibble van "uur" sec3 equ 1Dh ; linker nibble van "sec" delay1 equ 1Eh ; teller om een delay te maken tempreg equ 1Fh delay2 equ 20h tijddat2 equ 21h tell2 equ 22h ; variabele voor de schakelaar die bepaald of tijd of tijd/dat moet weergegeven worden bsr_temp equ 23h ORG 00h ; reset vector clrf decodeer bsf lengte, 7 ; signaal is weggevallen, dus eerst wachten op nieuwe minuut goto vector1 ORG 18h ; low priority vector (timer interrupt) goto vector2 delay movlw 0FFh movwf delay1 movlw 03h movwf delay2 verminder decfsz delay1 goto verminder decfsz delay2 goto verminder return decoder incf decodeer ; "decodeer" enkel verhogen indien het signaal net nog laag geweest is clrf hoog return overzetten clrf pariteit btfsc min, 0 ; pariteitscontrole incf pariteit ; bits samentellen en daarna kijken of het resultaat even is btfsc min, 1 incf pariteit btfsc min, 2 incf pariteit btfsc min, 3 incf pariteit btfsc min, 4 incf pariteit btfsc min, 5 incf pariteit btfsc min, 6 incf pariteit btfsc min, 7 incf pariteit btfsc pariteit, 0 ; als laatste bit = 0 dan is het resultaat even, dus antwoord klopt goto uren clrf min3 btfsc min, 0 bsf min3, 0 btfsc min, 1 bsf min3, 1 btfsc min, 2 bsf min3, 2 btfsc min, 3 bsf min3, 3 clrf min2 btfsc min, 4 bsf min2, 0 btfsc min, 5 bsf min2, 1 btfsc min, 6 bsf min2, 2 uren clrf pariteit btfsc uur, 0 ; pariteitscontrole incf pariteit ; bits samentellen en daarna kijken of het resultaat even is btfsc uur, 1 incf pariteit btfsc uur, 2 incf pariteit btfsc uur, 3 incf pariteit btfsc uur, 4 incf pariteit btfsc uur, 5 incf pariteit btfsc uur, 6 incf pariteit btfsc pariteit, 0 ; als laatste bit = 0 dan is het resultaat even, dus antwoord klopt goto datum clrf uur3 btfsc uur, 0 bsf uur3, 0 btfsc uur, 1 bsf uur3, 1 btfsc uur, 2 bsf uur3, 2 btfsc uur, 3 bsf uur3, 3 clrf uur2 btfsc uur, 4 bsf uur2, 0 btfsc uur, 5 bsf uur2, 1 datum clrf pariteit btfsc dag, 0 ; pariteitscontrole incf pariteit ; bits samentellen en daarna kijken of het resultaat even is btfsc dag, 1 incf pariteit btfsc dag, 2 incf pariteit btfsc dag, 3 incf pariteit btfsc dag, 4 incf pariteit btfsc dag, 5 incf pariteit btfsc weekdag, 0 incf pariteit btfsc weekdag, 1 incf pariteit btfsc weekdag, 2 incf pariteit btfsc maand, 0 incf pariteit btfsc maand, 1 incf pariteit btfsc maand, 2 incf pariteit btfsc maand, 3 incf pariteit btfsc maand, 4 incf pariteit btfsc jaar, 0 incf pariteit btfsc jaar, 1 incf pariteit btfsc jaar, 2 incf pariteit btfsc jaar, 3 incf pariteit btfsc jaar, 4 incf pariteit btfsc jaar, 5 incf pariteit btfsc jaar, 6 incf pariteit btfsc jaar, 7 incf pariteit btfsc lengte, 4 incf pariteit btfsc pariteit, 0 goto terug clrf dag3 btfsc dag, 0 bsf dag3, 0 btfsc dag, 1 bsf dag3, 1 btfsc dag, 2 bsf dag3, 2 btfsc dag, 3 bsf dag3, 3 clrf dag2 btfsc dag, 4 bsf dag2, 0 btfsc dag, 5 bsf dag2, 1 clrf maand3 btfsc maand, 0 bsf maand3, 0 btfsc maand, 1 bsf maand3, 1 btfsc maand, 2 bsf maand3, 2 btfsc maand, 3 bsf maand3, 3 clrf maand2 btfsc maand, 4 bsf maand2, 0 terug return een movf decodeer, w ; een systeempje om afhankelijk van de waarde van variabele movwf tempreg movlw HIGH cmd_tab movwf PCLATH movlw LOW cmd_tab movwf tempcmd movf tempreg,w addwf tempcmd,f btfsc STATUS, 0 incf PCLATH,f btfsc STATUS, 0 incf PCLATU,f addwf tempcmd,f btfsc STATUS, 0 incf PCLATH,f btfsc STATUS, 0 incf PCLATU,f movf tempcmd,w movwf PCL cmd_tab nop nop ; aankondigingsbits zijn niet belangrijk nop ; deze zijn enkel bedoelt voor analoge klokken nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop bsf min, 0 ; LSB wordt eerst uitgezonden bsf min, 1 ; minuten decoderen (7 bits) bsf min, 2 bsf min, 3 bsf min, 4 bsf min, 5 bsf min, 6 bsf min, 7 ; even pariteitsbit bsf uur, 0 ; uren decoderen (6 bits) bsf uur, 1 bsf uur, 2 bsf uur, 3 bsf uur, 4 bsf uur, 5 bsf uur, 6 ; even pariteit bsf dag, 0 ; dag v/d maand decoderen (6 bits) bsf dag, 1 bsf dag, 2 bsf dag, 3 bsf dag, 4 bsf dag, 5 bsf weekdag, 0 ; hier wordt de dag v/d week uitgezonden = irrelevant bsf weekdag, 1 ; maar wordt toch gedecodeerd omwille van de pariteit bsf weekdag, 2 bsf maand, 0 ; maand decoderen (5 bits) bsf maand, 1 bsf maand, 2 bsf maand, 3 bsf maand, 4 bsf jaar, 0 ; jaren zijn ook irrelevant bsf jaar, 1 bsf jaar, 2 bsf jaar, 3 ; deze hele codering lijkt misschien raar bsf jaar, 4 ; maar het geheim zit er hem in dat al de gedecodeerde info bsf jaar, 5 ; pas op het einde van de minuut gebruikt wordt bsf jaar, 6 bsf jaar, 7 bsf lengte, 4 ; pariteitsbit return nul bsf lengte, 5 movf decodeer, w ; een systeempje om afhankelijk van de waarde van variabele movwf tempreg movlw HIGH cmd_tab2 movwf PCLATH movlw LOW cmd_tab2 movwf tempcmd movf tempreg,w addwf tempcmd,f btfsc STATUS, 0 incf PCLATH,f btfsc STATUS, 0 incf PCLATU,f addwf tempcmd,f btfsc STATUS, 0 incf PCLATH,f btfsc STATUS, 0 incf PCLATU,f movf tempcmd,w movwf PCL cmd_tab2 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop bcf min, 0 ; LSB wordt eerst uitgezonden bcf min, 1 ; minuten decoderen (7 bits) bcf min, 2 bcf min, 3 bcf min, 4 bcf min, 5 bcf min, 6 bcf min, 7 ; even pariteitsbit bcf uur, 0 ; uren decoderen (6 bits) bcf uur, 1 bcf uur, 2 bcf uur, 3 bcf uur, 4 bcf uur, 5 bcf uur, 6 ; even pariteit bcf dag, 0 ; dag v/d maand decoderen (6 bits) bcf dag, 1 bcf dag, 2 bcf dag, 3 bcf dag, 4 bcf dag, 5 bcf weekdag, 0 ; hier wordt de dag v/d week uitgezonden = irrelevant bcf weekdag, 1 ; maar wordt toch gedecodeerd omwille van de pariteit bcf weekdag, 2 bcf maand, 0 ; maand decoderen (5 bits) bcf maand, 1 bcf maand, 2 bcf maand, 3 bcf maand, 4 bcf jaar, 0 ; jaren zijn ook irrelevant bcf jaar, 1 bcf jaar, 2 bcf jaar, 3 ; deze hele codering lijkt misschien raar bcf jaar, 4 ; maar het geheim zit er hem in dat al de gedecodeerde info bcf jaar, 5 ; pas op het einde van de minuut gebruikt wordt bcf jaar, 6 bcf jaar, 7 bcf lengte, 4 ; pariteitsbit return afhandeling movlw 02h cpfsgt hoog goto aa movlw 0E0h ; is het signaal langer laag dan 4 sec = signaal weggevallen cpfsgt laag ; dus alle gedecodeerde info wissen goto ab aa clrf uur clrf sec clrf min clrf dag clrf maand clrf laag clrf decodeer ; terug vanaf 0 beginnen decoderen bsf lengte, 7 return ab movlw 58h ; is het signaal langer laag dan 1,5 sec dan nieuwe minuut beginnen cpfsgt laag goto ac clrf decodeer bcf lengte, 7 ac btfsc lengte, 7 ; als het signaal weggevallen is stoppen met decoderen tot het terug is clrf decodeer movlw 09h ; hier pollen op ,15s cpfsgt hoog ; was het DCF-77 signaal langer hoog dan ,15s dan is er een 1 verstuurd call nul btfss lengte, 5 call een bcf lengte, 5 return vector2 movwf wvar ; werkregister in variabele "wvar" zetten, om op het einde terug te zetten movff STATUS, status_temp movff BSR, bsr_temp incf tijddat2 btfsc tijddat2, 2 incf tijddat ; tijd of datum weergeven? movlw 0FFh cpfslt tijddat clrf tijddat movlw 0FFh cpfslt tijddat2 clrf tijddat2 incf teller movlw 3Dh ; als "teller" = 61 (3D HEX) dan seconden verhogen cpfsgt teller ; alsook minuten en uren verder aanpassen goto volgende clrf teller incf sec3 movlw 09h ; als sec3 > 9 dan sec3 clearen en sec2 verhogen cpfsgt sec3 goto volgende incf sec2 clrf sec3 movlw 05h cpfsgt sec2 goto volgende incf min3 clrf sec2 movlw 09h cpfsgt min3 goto volgende incf min2 clrf min3 movlw 05h cpfsgt min2 goto volgende incf uur3 clrf min2 movlw 09h cpfsgt uur3 goto volgende incf uur2 clrf uur3 movlw 01h cpfsgt uur2 goto volgende movlw 03h cpfsgt uur3 goto volgende clrf uur2 clrf uur3 clrf min2 clrf min3 clrf teller volgende movlw 3Ah ; als het decoderen op z'n einde loopt de variabelen op z'n plaats zetten cpfslt decodeer call overzetten btfss signaal ; timer interrupt routine goto lag ; als DCF77-signaal laag is naar lag gaan goto hog ; en vice versa lag movlw 3Ah ; op de 59e bit seconden resetten cpfslt decodeer clrf sec2 cpfslt decodeer clrf sec3 cpfslt decodeer ; terug in de pas laten lopen clrf teller movlw 3Ch cpfslt decodeer clrf decodeer bcf lengte, 6 incf laag call afhandeling goto einde hog btfss lengte, 6 ; bij stijgende flank van het signaal call decoder ; variabele "decodeer" verhogen en "hoog" wissen bsf lengte, 6 clrf laag incf hoog movlw 50h cpfsgt hoog goto einde clrf decodeer clrf hoog einde movf wvar, 0 ; werkregister terug zetten movff bsr_temp, BSR movff status_temp, STATUS bcf INTCON, 2 ; flag bit terug op 0 zetten retfie vector1 movlb b'1111' movlw b'01110000' ; intosc op 8MHz movwf OSCCON movlw b'00010111' movwf OSCTUNE movlw b'11111111' movwf ADCON1 movlw b'00100001' ; poortconfiguratie (enkel bij opstarten) movwf TRISA movlw b'00000000' movwf TRISB movlw b'11100000' movwf INTCON movlw b'10000100' ; interrupt on change is low priority movwf INTCON2 ; timer interrupt is high priority movlw b'11000110' ; prescaler op 128 movwf T0CON ; om de 0.016384s een overflow bsf RCON, 7 ; priority enable movlb b'0000' movlw 01h movwf dag3 ; data wissen en datum op 01/01 zetten movwf maand3 clrf dag2 clrf maand2 clrf sec3 clrf sec2 clrf sec clrf uur3 clrf uur2 clrf uur clrf min3 clrf min2 clrf min clrf maand clrf dag clrf jaar clrf decodeer clrf laag clrf hoog bsf tell2, 6 ; standaard tijd tonen geen tijd/datum main btfsc PORTA, 5 ; tijd/datum of tijd? goto schak2 btfsc tell2, 7 goto schak1 bsf tell2, 7 goto schak3 schak3 btg tell2, 6 movlw 00B0h btfss tell2, 6 movwf tijddat goto schak1 schak2 bcf tell2, 7 schak1 btfsc tell2, 6 clrf tijddat btfsc tell2, 6 goto tijd movlw 00B0h ; 16 keer datum tonen (255-16) 239 keer tijd tonen cpfslt tijddat goto dat goto tijd tijd incf teller2 movlw 04h cpfslt teller2 clrf teller2 movlw 00h cpfseq teller2 goto ea movff min3, display ea movlw 01h cpfseq teller2 goto eb movff min2, display eb movlw 02h cpfseq teller2 goto ec movff uur3, display ec movlw 03h cpfseq teller2 goto nulde movff uur2, display goto nulde dat incf teller2 movlw 04h cpfslt teller2 clrf teller2 movlw 00h cpfseq teller2 goto ca movff maand3, display ca movlw 01h cpfseq teller2 goto cb movff maand2, display cb movlw 02h cpfseq teller2 goto cc movff dag3, display cc movlw 03h cpfseq teller2 goto nulde movff dag2, display nulde movlw 00h cpfseq display goto eerste movlw b'01101111' ; is min2 gelijk aan 0 dan 0 tonen enz.. movwf LATB goto aansturing eerste movlw 01h cpfseq display goto tweede movlw b'00000011' movwf LATB goto aansturing tweede movlw 02h cpfseq display goto derde movlw b'01011101' movwf LATB goto aansturing derde movlw 03h cpfseq display goto vierde movlw b'01011011' movwf LATB goto aansturing vierde movlw 04h cpfseq display goto vijfde movlw b'00110011' movwf LATB goto aansturing vijfde movlw 05h cpfseq display goto zesde movlw b'01111010' movwf LATB goto aansturing zesde movlw 06h cpfseq display goto zevende movlw b'01111110' movwf LATB goto aansturing zevende movlw 07h cpfseq display goto achtste movlw b'01000011' movwf LATB goto aansturing achtste movlw 08h cpfseq display goto negende movlw b'01111111' movwf LATB goto aansturing negende movlw b'01111011' movwf LATB aansturing movlw 00B0h ; als datum weergegeven wordt niet knipperen cpfslt tijddat goto knipper movlw 1Eh ; deze blok verzorgt de dubbele punt cpfslt teller goto knipper bsf LATB, 7 goto display1 knipper bcf LATB, 7 display1 movlw 00h ; afhankelijk van de data een ander display cpfseq teller2 ; onder spanning zetten goto display2 bcf LATB, 7 bcf LATA, 1 bsf LATA, 3 call delay goto main display2 movlw 01h cpfseq teller2 goto display3 bcf LATA, 3 bsf LATA, 4 call delay goto main display3 movlw 02h cpfseq teller2 goto display4 bcf LATA, 4 bsf LATA, 2 call delay goto main display4 bcf LATA, 2 bsf LATA, 1 bcf LATB, 7 call delay goto main end