Code:
Do ' MAIN - SCHLEIFE
Locate 1 , 16
If Dcf_pin = 1 Then Lcd "+" Else Lcd " " 'DCF-Impuls
Locate 1 , 6
If Dcf_status.7 = 1 Then Lcd "*" Else Lcd " " 'DCF-Status
Gosub Show_clock ' Anzeige vom RCT - Speicher holen
Gosub Show_alarm ' Anzeige vom RCT - Speicher holen
Gosub Hbl_pwm 'Hintergrundbeleuchtung
If Ta_alarm = 1 And Sw_alarm = 1 Then A = 1 Else A = 0
If V_al_std = Ds_hour And V_al_min = Ds_min Then B = 1 Else B = 0
If A = 1 And B = 1 Then C = 1 Else C = 0
If C = 1 And Ds_sec = 5 Then Gosub Ausgang
If Ta_alarm = 0 Then Gosub Al_stellen
Loop
Ausgang: ' AUSGANG
Al_out = 1
Sound Buzz , 200 , 150 'Buzzer Länge, Tonhöhe
Wait 1 'Alarm - EIN - Zeit
Al_out = 0
Return
Die Anzeige bleibt zwar für die Alarmzeit (1 bis 2 Sekunden) stehen, aber die Uhr läuft weiter.
Code:
'Ausgänge = B.1 = Alarm , B.2 = Buzzer , B.3 = HBL(PWM)
'C.4 und C.5 = TWI/I2C , Port D 2 bis D.7 für LCD
'Eingänge = , D.0 = Schalter Alarm Ein , D.1 = Taster Alarm stellen
'C.0 und C1 = ENC , C.2 = LDR für HBL , B.0 = DCF77
$regfile = "m8def.dat"
$crystal = 2000000
$hwstack = 64
$swstack = 32
$framesize = 64
$include "D:\PROG\INIT_LCD16x2.bas" 'LCD an Port D
$lib "I2C_TWI.lbx"
Config Sda = Portc.4
Config Scl = Portc.5
Config Twi = 100000
Ddrb = &B11001110
Portc = &B11 ' Pullups
Portd = &B11 'Pullups
Enc_a Alias Pinc.1
Enc_b Alias Pinc.0
Dcf_pin Alias Pinb.0
Al_out Alias Portb.1
Buzz Alias Portb.2
Hbl_out Alias Portb.3 'Beleuchtung Ausgang (PWM)
Sw_alarm Alias Pind.0 'Schalter Alarm EIN - AUS
Ta_alarm Alias Pind.1 'Taste Alarmzeit stellen EIN - AUS
Dim Al_zeit As Byte , A As Byte , B As Byte , C As Byte , Zw As Byte
Dim Ds_day As Byte , Ds_month As Byte , Ds_year As Byte
Dim Ds_sec As Byte , Ds_min As Byte , Ds_hour As Byte
Dim Al_min As Integer , Al_std As Integer , V_al_min As Byte , V_al_std As Byte
Dim Ldr As Word , Pwm_ As Byte 'LDR = Fotowiderstand
Al_min = 30 : Al_std = 20 'Startwert
Deflcdchar 1 , 2 , 6 , 14 , 31 , 14 , 6 , 2 , 32 'Pfeil nach links
'*********** TIMER 1 für DCF77****************
Config Dcf77 = Pinb.0 , Timer = 1
Config Date = Dmy , Separator = .
'*********** TIMER 0 für Drehencoder*********
Config Timer0 = Timer , Prescale = 64 '= ~2Mhz = ~0,5µs * 64 = ~ 32µs
Timer0 = 225 'Startwert = 31 x ~ 32µs = ~1ms
On Timer0 Enc_int
Enable Timer0
'*********** TIMER 2 und ADC 2 für Hintergrundbeleuchtung*********
Config Timer2 = Pwm , Prescale = 64 , Compare Pwm = Clear Up
Enable Timer2
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Enable Interrupts
Do ' MAIN - SCHLEIFE
Locate 1 , 16
If Dcf_pin = 1 Then Lcd "+" Else Lcd " " 'DCF-Impuls
Locate 1 , 6
If Dcf_status.7 = 1 Then Lcd "*" Else Lcd " " 'DCF-Status
Gosub Show_clock ' Anzeige vom RCT - Speicher holen
Gosub Show_alarm ' Anzeige vom RCT - Speicher holen
Gosub Hbl_pwm 'Hintergrundbeleuchtung
If Ta_alarm = 1 And Sw_alarm = 1 Then A = 1 Else A = 0
If V_al_std = Ds_hour And V_al_min = Ds_min Then B = 1 Else B = 0
If A = 1 And B = 1 Then C = 1 Else C = 0
If C = 1 And Ds_sec = 5 Then Gosub Ausgang
If Ta_alarm = 0 Then Gosub Al_stellen
Loop
Ausgang: ' AUSGANG
Al_out = 1
Sound Buzz , 200 , 150 'Buzzer Länge, Tonhöhe
Wait 1 'Alarm - EIN - Zeit
Al_out = 0
Return
Al_stellen: ' STELLEN
Do
Locate 2 , 8
If Al_std < 10 Then Lcd "0" ; Al_std Else Lcd Al_std
Locate 2 , 10
If Al_min < 10 Then Lcd ":0" ; Al_min Else Lcd ":" ; Al_min ; " "
Locate 2 , 14 : Lcd " " ; Chr(1) ; " "
If Al_min < 0 Then
Al_min = 59
Al_std = Al_std - 1
End If
If Al_std < 0 Then Al_std = 23
If Al_min > 59 Then
Al_min = 0
Al_std = Al_std + 1
End If
If Al_std > 23 Then Al_std = 0
Gosub Alarm_speichern
If Ta_alarm = 1 Then Exit Do
Loop
Enc_int: 'TIMER 0 Interrupt für Drehencoder
Timer0 = 225 'Timer Startwert
Zw.0 = Enc_a 'Zustandswechsel
Zw.1 = Enc_b
Select Case Zw
Case &H0_2 : Incr Al_min 'bei jedem zweiten Tick
Case &H0_1 : Decr Al_min
End Select
Zw.4 = Zw.0
Zw.5 = Zw.1
Return
Show_clock: ' RTC Uhrzeit und Datum auslesen und anzeigen
I2cstart
I2cwbyte 208
I2cwbyte 0
I2cstart
I2cwbyte 209
I2crbyte Ds_sec , Ack
I2crbyte Ds_min , Ack
I2crbyte Ds_hour , Ack
I2crbyte Ds_day , Ack
I2crbyte Ds_month , Ack
I2crbyte Ds_year , Nack
I2cstop
Gosub Rtc_stellen
Locate 1 , 1 : Lcd "Zeit:"
Locate 1 , 8 : Lcd Bcd(ds_hour) ; ":" ; Bcd(ds_min) ; ":" ; Bcd(ds_sec)
Return
Show_alarm: ' RTC Alarmzeit auslesen und anzeigen
I2cstart
I2cwbyte 208
I2cwbyte 10
I2cstart
I2cwbyte 209
I2crbyte V_al_std , Ack
I2crbyte V_al_min , Nack
I2cstop
Locate 2 , 1 : Lcd "Alarm: " ; Bcd(v_al_std) ; ":" ; Bcd(v_al_min)
Locate 2 , 14
If Sw_alarm = 0 Then Lcd "Aus" Else Lcd "Ein"
Return
Rtc_speichern: ' Uhrzeit in RTC speichern
Ds_sec = Makebcd(ds_sec)
Ds_min = Makebcd(ds_min)
Ds_hour = Makebcd(ds_hour)
Ds_day = Makebcd(ds_day)
Ds_month = Makebcd(ds_month)
Ds_year = Makebcd(ds_year)
I2cstart
I2cwbyte 208
I2cwbyte 0
I2cwbyte Ds_sec
I2cwbyte Ds_min
I2cwbyte Ds_hour
I2cwbyte Ds_day
I2cwbyte Ds_month
I2cwbyte Ds_year
I2cstop
Return
Alarm_speichern: ' Alarmzeit in RTC speichern
V_al_min = Makebcd(al_min)
V_al_std = Makebcd(al_std)
I2cstart
I2cwbyte 208
I2cwbyte 10
I2cwbyte V_al_std
I2cwbyte V_al_min
I2cstop
Return
Rtc_stellen: ' RTC nach DCF77 stellen
If Dcf_status.7 = 1 And Ds_sec <> _sec Then
Ds_sec = _sec
Ds_hour = _hour
Ds_min = _min
Ds_day = _day
Ds_month = _month
Ds_year = _year
Gosub Rtc_speichern
End If
Reset Dcf_status.7
Return
Hbl_pwm: 'Hintergrundbeleuchtung
Ldr = Getadc(2)
Shift Ldr , Right , 5 'Auflösung 5 Bit
If Ldr < 8 Then Pwm_ = 50
If Ldr > 15 Then Pwm_ = 255
Compare2 = Pwm_
Return
Hier noch ein Foto der gesamten Technik, aufgebaut mit myAVR-Light Board:
Lesezeichen