Qlocktwo : Le code
;Horloge qclocktwo picaxe 14M2 MM 14/04/2020
;poussoir de commande sur C.3
;interrupt sur C.0 :comptage pulses 1Hz, Déphasage de 2mn30s
;Mise au point par Afficheur LCD. les commandes sont restées en commentaires.
#picaxe 14M2
setfreq M32 ; Moins vite, ça fonctionne aussi
symbol pous=pinC.3
symbol eclair= C.2 ;sortie PWM
symbol LDR= C.4 ;entrée LDR
symbol buz=B.2 ;sortie buzzer pour les 3s mise à l'heure
symbol PM=bit0 ; bascule jour/nuit
symbol midinuit=bit1
symbol cpt1Hz=w13 ;compteur pulses 1Hz
symbol cptmax=w12 ;valeur max ;300 pour 5 mn
symbol heure=w11 ;heure sous forme HHmm
symbol lum=w10 ;mesure lumière (0 à 1023)
symbol varlum=w9 ;mesure après atténuation (170 à 1023)
symbol heuraff=w8
symbol hh=b1 ;valeut heures
symbol mm=b2 ;valeur minutes
symbol octet4=b3
symbol octet3=b4 ;octets pour pcf8574
symbol octet2=b5
symbol octet1=b6
symbol mmbcd=b7 ;valeur mn en BCD => DS3231
symbol hhbcd=b8 ;valeur HH en BCD
symbol varb=b10 ;variable locale
symbol dch=b11 ;variable locale, chiffre des dizaines
symbol coef=b12 ;coef lumière
symbol memomm=b13 ;mémo veleur précédente des minutes
symbol memoct2=b14
symbol vit=i2cslow_32
#macro transdectobcd(varb) ;transformation de dec vers bcd
dch=varb//10
varb=varb/10*16 'mises au format BCD
varb=varb+dch 'pour enregistrement
#endmacro
#macro transbcdtodec(varb) ;transformation de bcd vers dec
dch=varb/16*10
varb=varb//16
varb=varb+dch
#endmacro
pullup %100000000000 ;activation pullup sur C.3
pause 1000
pwmout pwmdiv64,eclair,255,1023 ;PWM sur C.2 488Hz ,100%. div16 =>1955 Hz
read 0,coef ;lecture niveau éclairage mis en mémoire EEPROM
if coef=0 then
coef=60 ;si pas en mémoire => éclairage max
endif
octet4=0:octet3=0:octet2=0:octet1=0
gosub afficheur
gosub affichmin
;serout B.0,T9600_32,(254,1,254,1,254,128,"OK")
If pous=0 then gosub initDS
gosub synchro ;suite mise àl'heure et perrte alimentation: recherche heure et mn
;***** boucle principale . Horloge 24H µC et réglage pour affichage sur 12H ********
do
do ;mise à l'échelle de lum à ajuster ?
readadc10 LDR,lum ;lecture LDR
lum=lum+10 max 1023
if pous=0 then gosub atenu ;atténuation éclairage
varlum=lum*coef/60
pwmduty eclair,varlum ;valeur % PWM (lum=0 =>0%, 1023 =>100%
gosub plusmoins ;ajout + ou - en fonction des minutes
loop while memomm=mm ;attente incrémentation des minutes (+5)
memomm=mm ;mm a changé =>mise en mémoire nouvelle valeur
cptmax=300 ;compteur 5 mn après 1er comptage
if mm>55 then ;après 55, on repasse
mm=0 ;à 0
inc hh ;et on incrémente l'heure
endif
if hh>23 then ;pendule H24
hh=0
endif
heure=hh*100 + mm ;heure en forme hhmm sur 24H
gosub convheur
loop
end
convheur: ;convertisseur H24 => H12 + nuit
select case heure ;passage en mode H12
case 0 to 0025
PM=1 ;pour minuit + mn
heuraff=heure
case 0030 to 1155
PM=0 ;=> AM pour afficher AM/PM
heuraff=heure ;0 midi ou minuit, pasd'affichage AM/PM
case 1200 to 1225
PM=0
heuraff= heure-1200
case 1230 to 2355
PM=1 ;=> PM et minuit
heuraff=heure-1200
endselect
;serout B.0,T9600_32,(254,192,"H24=",#heure," ","haff= ",#heuraff," ")
gosub codheur
gosub codmin
return
codheur: ;******* sub codage heure , octets 4 et 3 ***************
midinuit=0 ;par défaut
select case heuraff
case 0035 to 0130
octet4=2: octet3=2
case 135 to 230
octet4=131: octet3=0
case 235 to 330
octet4=67:octet3=0
case 335 to 430
octet4=3:octet3=1
case 435 to 530
octet4=19:octet3=0
case 535 to 630
octet4=3:octet3=8
case 635 to 730
octet4=35:octet3=0
case 735 to 830
octet4=3:octet3=16
case 835 to 930
octet4=3:octet3=4
case 935 to 1030
octet4=3:octet3=96
case 1035 to 1130
octet4=11:octet3=0
else ;reste 0 à 30 et 1135 à 1155
midinuit=1 ;il est midi ou minuit
if PM=1 then ;minuit
octet4=4:octet3=0
else ;midi
octet4=0:octet3=192
endif
end select
gosub afficheur
return
codmin: ;******* sub codage minutes octets 2 et 1 ********
select case mm
case 35
octet2=7 : octet1=33
case 40
octet2=5 : octet1=1
case 45
octet2=1 : octet1=81
case 50
octet2=1 : octet1=129
case 55
octet2=1 : octet1=33
case 00
octet2=0 : octet1=1
case 05
octet2=0 : octet1=33
case 10
octet2=0 : octet1=129
case 15
octet2=8 : octet1=17
case 20
octet2=4 : octet1=1
case 25
octet2=6 : octet1=33
case 30
octet2=8 : octet1=13
end select
octet1=octet1+PM
memoct2=octet2 ; pour sub plusmoins
if midinuit=1 then ;a midi ou à minuit:
octet1=octet1 & %11111100 ;on efface "AM" ou "PM"
endif
gosub afficheur ;si 1130-1230 => effacement AM PM
gosub affichmin
return
initDS: ;******* Initialisation DS3231;'%11010000 est l'adresse i2c******
do loop while pous=0
time=0
PM=0
sound buz,(103,100)
do ;réglage AM/PM (jour/PM)
if pous=0 then
pause 100 ;anti rebonds logiciel
time =0
do
if time >3 then
sound buz,(103,100)
goto heur
endif
loop while pous=0
PM=not PM
octet1=PM +1 ;càd 1 ou 2
gosub affichmin ;on affiche "AM" ou "PM"
endif
loop
heur:
do loop while pous=0
time=0 : hh=0 : mm=0
do ;réglage heures
if pous=0 then
pause 100
time =0
do
if time >3 then
sound buz,(103,100)
goto minute
endif
loop while pous=0
inc hh
if hh>11 then ;càd 12
hh=0
endif
endif
heuraff=100*hh
gosub codheur
gosub codmin
loop
minute:
do loop while pous=0 ;on a choisi l'heure
time=0 : mm=0
do ;réglage minutes
if pous=0 then
pause 100
time =0
do
if time >3 then
sound buz,(103,100)
goto fin
endif
loop while pous=0
mm=mm+5
if mm>55 then ;càd 60
mm=0
endif
endif
gosub codmin
loop
fin:
if hh>0 then
if mm>30 then
hh=hh-1
endif
hh=12*PM+hh
endif
if hh=0 then
if mm>30 then
hh=12*PM+11
endif
if mm<35 and PM=1 then
PM=not PM
hh=12*PM
endif
endif
do loop while pous=0 ;attente relache
memomm=mm
mmbcd=mm ;mmbcd est la forme BCD de mm sur 1 octet
hhbcd=hh
;serout B.0,T9600_32,(254,212,"H24=",#hh,#mm)
transdectobcd(mmbcd)
transdectobcd(hhbcd)
do loop while pous=1 ;on attend
do loop while pous=0 ;on relâche à sec=00
hi2csetup i2cmaster, %11010000, i2cslow, i2cbyte
hi2cout 0, ($00,mmbcd,hhbcd,$0,$0,$0,$0,%00010000) ;mise en mémoire EEPROM
hi2cout 14,(0) ;registre control DS3231 au cas où
sound buz,(103,100)
pause 50
sound buz,(103,100)
octet4=0:octet3=0:octet2=0:octet1=0 ;on
gosub afficheur ;efface
gosub affichmin ;tout (presque)
return
afficheur: ;affichage des l'heures
hi2csetup i2cmaster,%01001000, vit, i2cbyte ;adresse I2C à ajuster
hi2cout (octet4)
hi2csetup i2cmaster,%01000110, vit, i2cbyte ;adresse I2C à ajuster
hi2cout (octet3)
;serout B.0,T9600_32,(254,128," 4=",#octet4," 3=",#octet3," 2=",#octet2," 1=",#octet1," ",254,212,"haff= ",#heuraff," ","N=",#PM," ")
return
affichmin: ;affichage des minutes
hi2csetup i2cmaster,%01000100, vit, i2cbyte ;adresse I2C à ajuster
hi2cout (octet2)
hi2csetup i2cmaster,%01000010, vit, i2cbyte ;adresse I2C à ajuster
hi2cout (octet1)
;serout B.0,T9600_32,(254,128,"4=",#octet4," 3=",#octet3," 2=",#octet2," 1=",#octet1," ")
;serout B.0,T9600_32,(254,192,"haff=",#heuraff," ",#mm," PM=",#PM," ")
;serout B.0,T9600_32,(254,212,"h24=",#heure," " )
return
synchro: ;sous prog resynchronosation
hi2csetup i2cmaster, %11010000, i2cslow, i2cbyte ;en cas de coupure d'alim
hi2cout 14,(0) ;registre control DS3231
hi2cout 7,(%00010000) ;registre control DS1307
do
hi2cin 1,(mm) ;lecture minutes et heures sur RTC
hi2cin 2,(hh)
transbcdtodec(mm) ;passage forme bcd => dec
transbcdtodec(hh)
varb= mm//5 ;attente mn multiple de 5
;serout B.0,T9600_32,(254,1,254,148,"hhmm=",#hh," ",#mm," ")
loop while varb<>0 or memomm=mm ;pour attendre la valeur suivante
cpt1Hz=0 ;raz compteur
setint %1,%1 ;interruption niveau 1 sur C.0; comptage
cptmax=150 ;comptage pour décalage 2mn30s
heure=hh*100+mm ;mise en forme hhmm
memomm=mm
return
atenu: ;***** sub atténuation éclairage *******
pause 100
do loop while pous=0
coef=coef+10
if coef>60 then
coef=0 ;de 0 à 60 => 7 paliers
endif
write 0,coef ;mise en mémoire EEPROM
return
plusmoins:
octet2=memoct2
if cpt1Hz < 90 and cptmax=300 then
octet2=octet2 | 128 ; ajoute 1 sur bit 7 (de 0 à 7)
elseif cpt1Hz >210 and cptmax=300 then
octet2=octet2 | 64 ;ajout 1 sur bit 6
endif
hi2csetup i2cmaster,%01000100, vit, i2cbyte ;adresse I2C à ajuster
hi2cout (octet2)
;serout B.0,T9600_32,(254,148,"oct2=",#octet2," moc2=",#memoct2," ",254,222,"cpt=",#cpt1Hz," ")
return
interrupt: ;comptage de secondes RTC
inc cpt1Hz
if cpt1Hz>=cptmax then ;a cptmax, on incrément les minutes
cpt1Hz=0 ;raz compteur
mm=mm+5 ;on augmente les minutes de 5
endif
do loop while pinC.0=1 ; un seul inc par seconde
setint %1,%1 ;réactivation interruption
return