'////////////////////////////////////////////////////////// '/// FastAVR Basic Compiler for AVR by MICRODESIGN /// '/// DCF77 receiver STK-500 www.FastAVR.com /// '/// ___ ________ _________ ____ pulses are /// '/// |_| |__| |_| active LOW /// '/// about 100ms for LOW and 200ms for HIGH, but /// '/// must be measured with max 25ms before using /// '/// sampling DCF line every 25ms using interrupt /// '////////////////////////////////////////////////////////// $Device = 4433 ' used device $Stack = 32 ' stack depth $Clock = 7.3728 ' adjust for used crystal $Timer1 = Timer, Prescale=256, Compare=DisConnect, Clear $Def DCF = PIND.2 $Def LED = PORTD.4 $LeadChar="0", Format(2,0) $Baud = 9600 Declare Interrupt Oc1A() Declare Sub Init() Declare Sub ReceiveDCF() Declare Sub StoreBit() Declare Sub ProcessData() Dim LOtime As Byte, HItime As Byte, State As Byte Dim DCFsec As Byte, CurDCF As Bit, BitDCF As Bit Dim DCFmin As Byte, DCFhour As Byte Dim DCFday As Byte, DCFmonth As Byte, DCFdow As Byte, DCFyear As Byte Dim Parity As Bit, par1 As Bit, par2 As Bit, par3 As Bit Dim n As Byte Const True=1, False=0 Const StartBitLen=150 Const BitTime=15 ' beetween Highest LOW and Lowest HIGH Const BitMin=70 ' min HItime + LOtime Const BitMax=130 ' max HItime + LOtime 'names for States (Enum) Const IdleState=0 Const WaitStartBit=1 Const InStartBit=2 Const GetBit=3 Const NextBit=4 Const DataReady=5 Const Error=6 Init() Do ' YourSubs() LED = DCF ' LED for monitoring pulses ReceiveDCF() Loop '/////////////////////////////////////////////////////// Sub Init() Set DDRD.4 ' here is LED Compare1=&h0120 '10ms @ 7.3728 Start Timer1 Enable Oc1A Enable Interrupts State=Error End Sub '/////////////////////////////////////////////////////// Interrupt Oc1A(), Save 2 ' we are here every 25ms If DCF=CurDCF Then If DCF Then Incr HItime Else Incr LOtime End If Else If DCF Then HItime=0 Else LOtime=0 End If CurDCF=DCF End If End Interrupt '/////////////////////////////////////////////////////// Sub ReceiveDCF() Local tmp As Byte Select Case State ' state machine Case IdleState ' 0 If Not CurDCF Then State=WaitStartBit Case WaitStartBit ' 1 If CurDCF Then State=InStartBit Case InStartBit ' 2 If Not CurDCF Then If HItime>StartBitLen Then State=GetBit DCFsec=0 Else State=IdleState End If End If Case GetBit ' 3 If CurDCF Then If LOtime58 Then DCFsec=0 State=DataReady parity=0 End If End If Case NextBit ' 4 If Not CurDCF Then tmp=LOtime+HItime If tmpBitMax Then 'check State=Error Else State=GetBit End If End If Case DataReady ' 5 If par1 Or par2 Or par3 Then 'parity check State=Error Else ProcessData() State=InStartBit End If Case Error ' 6 Print "NOK" DCFsec=0 State=IdleState parity=0 End Select End Sub '/////////////////////////////////////////////////////// Sub ProcessData() Print dcfhour;":";DCFmin End Sub '/////////////////////////////////////////////////////// Sub StoreBit() ' you can comment out unwanted Select Case DCFsec ' minutes Case 21 DCFmin=BitDCF Case 22 If BitDCF Then DCFmin=DCFmin+2 Case 23 If BitDCF Then DCFmin=DCFmin+4 Case 24 If BitDCF Then DCFmin=DCFmin+8 Case 25 If BitDCF Then DCFmin=DCFmin+10 Case 26 If BitDCF Then DCFmin=DCFmin+20 Case 27 If BitDCF Then DCFmin=DCFmin+40 Case 28 If Parity=BitDCF Then par1=False Else par1=True End If ' hours Case 29 DCFhour=BitDCF Case 30 If BitDCF Then DCFhour=DCFhour+2 Case 31 If BitDCF Then DCFhour=DCFhour+4 Case 32 If BitDCF Then DCFhour=DCFhour+8 Case 33 If BitDCF Then DCFhour=DCFhour+10 Case 34 If BitDCF Then DCFhour=DCFhour+20 Case 35 If Parity=BitDCF Then par2=False Else par2=True End If Case 36 DCFday=BitDCF Case 37 If BitDCF Then DCFday=DCFday+2 Case 38 If BitDCF Then DCFday=DCFday+4 Case 39 If BitDCF Then DCFday=DCFday+8 Case 40 If BitDCF Then DCFday=DCFday+10 Case 41 If BitDCF Then DCFday=DCFday+20 ' day of week ' Case 42 ' DCFdow=BitDCF ' Case 43 ' If BitDCF Then DCFdow=DCFdow+2 ' Case 44 ' If BitDCF Then DCFdow=DCFdow+4 ' month Case 45 DCFmonth=BitDCF Case 46 If BitDCF Then DCFmonth=DCFmonth+2 Case 47 If BitDCF Then DCFmonth=DCFmonth+4 Case 48 If BitDCF Then DCFmonth=DCFmonth+8 Case 49 If BitDCF Then DCFmonth=DCFmonth+10 ' year Case 50 DCFyear=BitDCF Case 51 If BitDCF Then DCFyear=DCFyear+2 Case 52 If BitDCF Then DCFyear=DCFyear+4 Case 53 If BitDCF Then DCFyear=DCFyear+8 Case 54 If BitDCF Then DCFyear=DCFyear+10 Case 55 If BitDCF Then DCFyear=DCFyear+20 Case 56 If BitDCF Then DCFyear=DCFyear+40 Case 57 If BitDCF Then DCFyear=DCFyear+80 Case 58 If Parity=BitDCF Then par3=False Else par3=True End If End Select Parity=Parity Xor BitDCF End Sub