'**********************************************************************************
' Funkuhr mit 60 Sekundenanzeige und LED-Segmente +Datum
'**********************************************************************************
' Ansteuerung 74HC595 und SAA 1064
' Programm für Open Micro
' Progammsprache OC-Basic
' 05.01. 2007 Senderoutine HC 595 Basic Compiler
' Lichtsensor 06.01.07
' 12 Stunden LEDs gedimmt 08.01.2007
' 14.01.2007 Senderoutine SAA auf Maschinencode
' 22.01.2007 Führende Null Stunden entfernt, alle 5 sec Helligkeitreglung
' 27.02.2007 Version wird im Datum abgelegt day month year, neueres datum neuere Version
' 01.03.2007 Helligkeit nur noch 1 x pro Minute
' 22.03.2007 ab 22 uhr bis 8 uhr nur eine Sekunde anzeigen
' 24.04.2007 Pinbelegung
' 16.05.2007 Zeit manuell stellen
' 23.06.2007 Temperaturanzeige Innen
' 14.09.2007 Temperatur Aussen
' 05.11.2007 Datum Temperatur wechsel alle 5 sec. Minuszeichen variabel.
' 08.12.2007 Für Uhr 06
'**********************************************************************************
'
' Nach der Aktivierung wird das DCF77-Signal von den DCF77-Empfangsroutinen
' im Hintergrund, waehrend der normalen Programmausfuehrung, dekodiert und
' die interne Uhr (RTC) der OM gestellt.
' Es muss der invertierte Ausgang des preiswerten DCF77-Empfangsmoduls mit
' der Conrad-Bestellnummer 641138 an PORT[4] angeschlossen werden. Sicher-
' heitshalber sollte ein Pull-Up-Widerstand 10 kOhm zwischen Ausgang und
' +5 Volt geschaltet werden.
' Die Pinbelegung der
' Open-Mini (QY4)
' ______________
' | | P 3 wird bei der Programmübertragung auf 0 V gelegt (Jumper)
' [ P 3 P 4 ] P 4 Signal vom DCF Empfänger, Auswertung über Interrupt
' | | P 12 Taster Zeiteinstellung manuell, Stellen
' [ P 12 P 13 ] P 13
' | | P 11 Taster Zeiteinstellung manuell, Set
' [ P 11 P 14 ] P 14 Strobe 74 HC 595
' | | P 2 PWM für Helligkeitsregelung 74 HC 595
' [ P 2 P 5 ] P 5 AD 5 Temperatur innen
' | | P 1 Serielle Schnittstelle, über Jamper AD 1 Temperatur außen
' [ P 1 P 6 ] P 6 wird als AD 6 verwendet, Fotowiderstand
' | | P 10 SCL I2C Bus
' [ P 10 P 15 ] P 15 Clock 74 HC 595
' | | P 9 SDA I2C Bus
' [ P 9 P 16 ] P 16 Daten 74 HC 595
' | |
' [ VSS VDD ] VDD = 4.6 bis 5.5 Volt
' |_____/ \_____| Vss = Gnd, Masse
'
' ---------------------------------------------------------------------------
INCLUDE "om.def" 'Definitionen fuer Open-Micro und Open-Mini
define Tasterzeit port[12]
define Tasterset port[11]
define TempI ad[5]
define TempA ad[1]
define Helligkeit ad[6] 'Fotowiderstand
define Clock port[15] ' Pin 11 an 74HC595 Takt
define Strobe port[14] ' Pin 12 an 74HC595 Daten Übernahme
define Daten port[16] ' Pin 14 an 74HC595 Daten
define data byte 'Variable für Datenausgabe 595
define databit bit[8] of data 'das höchstwertige Bit von Data
define i byte 'Variable
define ii byte
define Digit1 byte ' Sekundenleds
define Digit2 byte
define Digit3 byte
define Digit4 byte
define DIGIT5 byte
define DIGIT6 byte
define DIGIT7 byte
define DIGIT8 byte
define d1 byte
define d2 byte
define d3 byte
define d4 byte
define d7 byte
define d8 byte
define sek byte 'Sekunde merken
define hell byte 'Helligkeit für PWM
define hell1 byte
DEFINE temp BYTE
define iii byte 'Variable
define iicdata byte
'-------------------------
define Adresse &B01110000 'Adresse SAA 1064 bei 0V
define BRIGHT &B00000111 '&H07 0 mA ' Helligkeit = aus
define BRIGHT1 &B00010111 '&H17 3 mA +16
define BRIGHT2 &B00100111 '&H27 6 mA +32
define BRIGHT3 &B00110111 '&H37 9 mA +48
define BRIGHT4 &B01000111 '&H47 12 mA +64
define BRIGHT5 &B01010111 '&H57 15 mA +80
define BRIGHT6 &B01100111 '&H67 18 mA +96
define BRIGHT7 &B01110111 '&H77 21 mA +112
' ---------------------------- Hauptprogramm ---------------------------------------
'
' ---------------------------------------------------------------------------
' Die Empfangsroutinen fuer DCF77 einbinden
' ---------------------------------------------------------------------------
INCLUDE "dcf778.iia"
' ---------------------------------------------------------------------------
' Das Hauptprogramm
' ---------------------------------------------------------------------------
#main
' Print Freq2 'Wert des internen Taktgebers auslesen
'freq2 = freq2 +1 'Internen Taktgeber trimmen
'pause 100 'das ist nur bei großer Gangungenauigkeit der Uhr nötig,
'print freq2 'besser mit dem Programm osctrim.exe den Prozessor neu trimmen.
' Auszug aus der Dokumentation:
' Auf der OM läßt sich mit dieser internen Variable der Systemtakt von 3,2 MHz justieren
' FREQ2 entspricht dem Kontroller-Register OSCTRIM auf Adresse $38.
' Mit diesem Register wird die Größe des internen Kondensators verändert,
' der Verwendung im internen Oszillator findet.
' Durch Erhöhen des FREQ2-Werts um eins wird auch die Periodendauer um rund 0,2% erhöht.
' Die Taktfrequenz wird also niedriger. Die interne Uhr geht langsamer.
UIRTofl = ON ' Die Assembler Routine aufrufen
gosub ini
day = 08 'wird als Versionsnummer interpretiert
month = 12
year = 07
minute = 59
hour = 08
second = 50
gosub digit_ini
PWM2_ein ' PWM-Routine Port2 einschalten
hell = 220
PWM2 hell
hell = 5
#loop
if hour = 24 then 'Wenn Mitternacht kein Empfang
hour = 0
day = day +1 'Pech wenn der Monatsletzte
end if
if second = sek then loop ' wartet bis eine Sekunde um ist
sek = second
'--------------------------------------------------------------------------------------
' Sekunden anzeigen
'--------------------------------------------------------------------------------------
if (hour < 8) or (hour > 21) then
gosub alle60
else
if minute > 30 then
gosub vorwaerts
else
gosub alle60
end if
end if
gosub zeit
'--------------------------------------------------------------------------------------
if (sek mod 5) = 0 then gosub datum ' Datum
'--------------------------------------------------------------------------------------
if sek = 30 then ' nur einmal pro Minute anzeigen
' wenn man alle Sekunde anzeigt ist die Anzeige zu unruhig.
hell = helligkeit -10 'damit die Anzeige bei Dunkelheit noch leuchtet
'if hell > 248 then hell = 248 'nicht ganz dunkel
PWM2 hell 'für Minuten und Stundenanzeige (Große Anzeige) sowie die 12 StundenLeds
hell = Helligkeit / 30 ' für SekundenLeds
if hell > 6 then hell = 6
'print freq2
end if
'--------------------------------------------------------------------------------------
'Zeitkorektur Feineinstellung
if (sek =40 ) and (minute mod 6 = 0 ) then gosub korrektur ' bei Störung Funksignal
' alle x Minuten eine Sekunde zurück
'--------------------------------------------------------------------------------------
if tasterset = off then goto zeiteinstellen
goto loop
end
' ---------------------------------------------------------------------------
'------------------------------------------------------------------------------------------------------
'Anzeigen
'------------------------------------------------------------------------------------------------------
#Zeit
'--------------------------------------------------------------------------------------
'Minuten und Stunden
'--------------------------------------------------------------------------------------
ii = minute mod 10 : Data = looktab (dec595, ii)
schreiben
temp = 1
if (DCF_OK = 0) and (sek mod 5 = 0) then temp = 0
ii = minute /10 : Data = looktab (dec595, ii)+ temp ' kein Funksignal dann blinkt der Doppelpunkt
schreiben
ii = hour mod 10 : Data = looktab (dec595, ii)
schreiben
ii = hour /10
if ii = 0 then ' Null bei Stundenanzeige unterdrücken
Data = 1
else
Data = looktab (dec595, ii)+1 ' +1 = Helligkeit der 12 Stunden LEDs
end if
schreiben
pulse strobe
return
#korrektur
if dcfmerk <> minute then
second = second -1
dcfmerk = minute
end if
return
#datum
d1 = Digit1 ' wert merken
d2 = Digit2
d3 = Digit3
d4 = Digit4
d7 = Digit7
d8 = Digit8
if (sek = 0)or (sek = 15) or (sek = 30)or (sek = 45)then
Digit3= month / 10: DIGIT3 = looktab (decoder, Digit3)
Digit4= day / 10: DIGIT4 = looktab (decoder, digit4)
Digit2= day mod 10: DIGIT2 = looktab (decoder, Digit2) +128
Digit1= month mod 10: DIGIT1 = looktab (decoder, digit1) +128
'Digit6= Year / 10: DIGIT6 = looktab (decoder, Digit6)
'Digit5= Year mod 10: DIGIT5 = looktab (decoder, digit5)
Digit8= Year / 10: DIGIT8 = looktab (decoder, Digit8)
Digit7= Year mod 10: DIGIT7 = looktab (decoder, digit7)
else
pullupA=&B00101110
if(sek = 5) or (sek = 20)or (sek = 35)or (sek = 50) then 'Innentemperatur
temp = looktab (temptab, TempI -100)
digit4 = &B01001000 'I innen
else
temp = looktab (temptab, TempA -100) 'Justieren -100 = Orginal -102 = Temperatur um ca. 1 Grad erhöhen
digit4 = &B01011111 'A außen
end if
if temp > 100 then
temp = temp -100
Digit2 = &B00000001 '= - bei Minus Temperaturen
else
digit2 = 0 ' nicht anzeigen
end if
Digit3 = temp/ 10
if DIGIT3 >0 then Digit3 = looktab (decoder, Digit3) 'nur anzeigen wenn größer 0
Digit1= temp mod 10: DIGIT1 = looktab (decoder, digit1)
if (Digit2 = &B00000001) and (Digit3 = 0) then 'Minuszeichen eine Stelle vor
digit3 = 1
digit2 = 0
end if
digit8 = &B00001111 '=°
digit7 = &B00110110 '=C
end if
i = 2 'Adresse
ii = 4
hell1 = helligkeit / 40
on hell1 gosub null, eins,zwei,drei,vier,fuenf,sechs
sendbuf
UIRTofl = ON
Digit1 = d1
Digit2 = d2
Digit3 = d3
Digit4 = d4
Digit7 = d7
Digit8 = d8
return
#alle60
temp = second
gosub anzeigen
if second = 0 then goto rueck
return
#rueck
dbnzctr= 60 ' das gleiche rückwärts
#loop1
temp = dbnzctr
gosub anzeigen
dbnz loop1
return
#Anzeigen
i = temp/ 8
ii = temp mod 8
gosub digit_ini
add ii, 16
on i gosub erste, zweite, dritte, vierte, fuenfte, sechste, siebente, achte
i = 0 'adresse
ii = 6
on hell gosub null, eins,zwei,drei,vier,fuenf,sechs
sendbuf
return
#null
iii = bright7
return
#eins
iii = bright6
return
#zwei
iii = bright5
return
#drei
iii = bright4
return
#vier
iii = bright3
return
#fuenf
iii = bright2
return
#sechs
iii = bright1
return
'--------------------------------------------------------------------------------------
'Sekundenleds alle 60 anschalten, danach alle ausschalten.
'--------------------------------------------------------------------------------------
#Vorwaerts
i = sek / 8
ii = sek mod 8
if minute mod 2 = 1 then add ii, 8
on i gosub erste, zweite, dritte, vierte, fuenfte, sechste, siebente, achte
i = 0
ii = 6
on hell gosub null, eins,zwei,drei,vier,fuenf,sechs
sendbuf
return
' ----------------------------- Initialisierung--------------------------------------
#ini
Clock = off 'pin 11 (shift Register clock input)
Strobe= off 'pin 12 (Daten Übernahme)
Daten = off 'pin 14 (serieller Daten input)
data = 0
schreiben
data = 0
schreiben
data = 0
schreiben
data = 0
schreiben
pulse strobe
Return
' ----------------------------- Ausgabe--------------------------------------
procedure schreiben compile
for temp = 1 to 8
daten = databit
pulse clock
data = data shl 1
next
return
end procedure
'--------------------------------- Sekundenanzeige---------------------------------
'--------------------------------------------------------
'---- TREIBER LED-DISPLAY MIT IIC-BUS SAA1064
'--------------------------------------------------------
#erste
Digit1 = looktab (reihe,ii)
Return
#zweite
Digit2 = looktab (reihe,ii)
Return
#dritte
Digit3 = looktab (reihe,ii)
Return
#vierte
Digit4 = looktab (reihe,ii)
Return
#fuenfte
Digit5 = looktab (reihe,ii)
Return
#sechste
Digit6 = looktab (reihe,ii)
Return
#siebente
Digit7 = looktab (reihe,ii)
Return
#achte
Digit8 = looktab (reihe,ii)
Return
#digit_ini
Digit1 = 0
Digit2 = 0
Digit3 = 0
Digit4 = 0
Digit5 = 0
Digit6 = 0
Digit7 = 0
Digit8 = 0
Return
'------------------------------------------------------
'IIIIIIIIIII Sende-Routine in Maschinensprache aufrufen
'------------------------------------------------------
#SENDBUF
I2C_START 'Start
i2c_write(Adresse + i) 'Adresse
i2c_write(0) 'INSTRUCTION
i2c_write(iii) 'CONTROL Helligkeit
i2c_write(DIGIT1)
i2c_write(DIGIT3)
i2c_write(DIGIT2)
i2c_write(DIGIT4)
I2C_stop
I2C_START
i2c_write(Adresse + ii)
i2c_write(0)
i2c_write(iii)
i2c_write(DIGIT5)
i2c_write(DIGIT7)
i2c_write(DIGIT6)
i2c_write(DIGIT8)
I2C_stop
return
#zeiteinstellen
wait tasterset = on
second = 1
while tasterset = on
if tasterzeit = off then
hour = hour +1
if hour > 23 Then hour = 0
gosub zeit
wait tasterzeit = on
end if
wend
wait tasterset = on
while tasterset = on
if tasterzeit = off then
minute = minute +1
if minute > 59 Then minute = 0
gosub zeit
wait tasterzeit = on
end if
wend
wait tasterset = on
second = 1
goto loop
' ---------------------------------------------------------------------------
' ---------------------------------------------------------------------------
' --- PWM-Routinen für Port2 ------------------------------------------------
' ---------------------------------------------------------------------------
TABLE pwm2_ein byte ' PWM Port2 einschalten
&h12 &h06
&h1a &h20 &h18 &h20 &h3f &h29 &h3f &h2a &ha6 &h1a &hb7 &h28 &h1b &h20 &h81
TABEND
' ---------------------------------------------------------------------------
TABLE pwm2 byte ' PWM Port2 setzten - Uebergabe als Argument
&h12 &h06
&had &h13 &ha1 &hfa &h25 &h03 &h10 &h28 &h81 &h5f &h48 &h59 &h48 &h59 &hbf &h29
&hb7 &h2a &h11 &h28 &h81 &hae &h01 &h83
TABEND
INCLUDE "om_i2cx.pro" 'Routinen fuer I2C-Bus einbinden von Dietmar Harlos
INCLUDE "om_fw.pro" 'Firmwareroutinen einbinden
Table dec595 byte 'für große 7 Seg Leds Min und Stunden
' Bits sind von 1 bis 7 durchnummeriert
'z.B. die "1" wird durch das 4 und 6 Bit dargestellt.(&01001000)
'das 0te bit wird für die Helligkeitsregelung benötigt.
'
' 3
' 2 4
' 5
' 1 6
' 7
' 0 1 2 3 4 5 6 7 8 9
&B11011110,&B01010000,&B10111010, &B11111000, &B01110100, &B11101100, &B11100110,&B01011000, &B11111110,&B01111100
tabend
table reihe byte 'für den 60 Sekundenring
1, 3, 7, 15, 31, 63, 127, 255, 254, 252, 248, 240, 224, 192, 128, 0, 1, 2, 4, 8, 16, 32, 64, 128
tabend
Table Decoder byte ' für kleine 7 Seg_Anzeige Datum
' Bits sind von 0 bis 7 durchnummeriert
'z.B. die "1" wird durch das 3 und 6 Bit dargestellt.(&01001000)
'das 7te bit wird nicht benötigt.
'
' 2
' 1 3
' 0
' 4 6
' 5
' 0 1 2 3 4 5 6 7 8 9
&B01111110,&B01001000,&B00111101 ,&B01101101,&B01001011,&B01100111,&B01110011,&B01001100,&B01111111,&B01001111
tabend
table TempTab byte 'Temperatur von 37 Grad + bis 27 Grad -
99
'1 2 3 4 5 6 7 8 9
37 37 36 36 35 35 34 34 33 33
32 32 31 31 30 30 29 29 28 28
27 27 26 26 25 25 24 24 24 23
23 23 22 22 22 21 21 21 20 20
20 19 19 18 18 17 17 17 16 16 '150
15 15 14 14 14 13 13 12 12 11
11 11 10 10 9 9 8 8 7 7
6 6 5 5 4 4 3 3 2 2
1 1 1 0 0 0 0 0 101 101
101 102 102 103 103 104 104 105 105 106 '200
106 107 107 108 108 109 110 110 111 111
112 113 113 114 115 116 116 117 117 118
119 119 120 121 122 123 124 125 126 127
tabend