|

楼主 |
发表于 2017-2-8 16:39:42
|
显示全部楼层
电压表时钟 · 源程序
2017-01-16 WTH 无线电杂志
电压表时钟的正文,请看一楼
;源程序由WTH编写,运行于PicAxe
14M2上,阅读程序可以让你了解思
路。
; Project Name: 3 Panel Meter Clock
; REV: FIN (everything works fine with
clock and temp)
;
; Start Date: Feb 12, 2012
;
; Program Rev History/Ideas:
; - to set clock push M or H button
; - push main button to display temp
F, C, and K
; - Routine to drive 3 meters to full
scale when main button AND (M OR
H)
; is pressed. This is to allow
adjustment of trimmers to full scale.
; Adjustment to zero scale should be
done first with power off.
;
; *******************************
; PICAXE PE Rev: MacAXEPad 1.3.2
;
#picaxe14m2
'define memory locations as symbols
symbol hour_meter = c.0 'LEG 7
symbol minute_meter = c.2 'LEG 5
symbol second_meter = b.2 ' LEG 11
symbol temp_switch = pinc.4 ' LEG3
symbol temp_sensor = b.5 'LEG8
symbol hour_set = pinc.3 'LEG3
symbol minute_set = pinc.1 'LEG6
symbol CthermoValue = b10
symbol FthermoValue = b11
symbol KthermoValue = w6 'b12 and
b13
symbol seconds = b0
symbol minutes = b1
symbol hours = b2
symbol day = b3
symbol date = b4
symbol month = b5
symbol year = b6
symbol blinky = b7
symbol Tens_Digi = b8 ;Used to get
the Tens Digit from the $HEX RTC
value
symbol Ones_Digi = b9 ;Used to get
the Ones Digit from the $HEX RTC
value
' w7 (b14 and b15) is used to control
the PCM to the meters
' Set the time on the DS1307 RTC
i2cslave %11010000, i2cslow, i2cbyte ;
set PICAXE as master and DS1307
slave address
pause 50
'Set all meters to full scale with 100%
duty cycle
pwmout hour_meter,99,400
pwmout minute_meter,99,400
pwmout second_meter,99,400
'\/ \/ \/ \/ Un_REM THESE LINES
(BELOW) IF SETTING UP A NEW RTC \/
\/ \/ \/
#rem
' Set the RTC chip time
; write time and date e.g. to 11:59:00
on Thurs 25/12/03
'; would be "writei2c 0,($00, $59, $11,
$03, $25, $12, $03, 010000)"
' readi2c 0, (b0,b1,b2,b3,b4,b5,b6,b7)
reads back the data
let seconds = $00 ; 00-59 Note all
BCD format
let minutes = $00 ; 00-59 Note all
BCD format
let hours = $01 ; 01-12 Note all BCD
format
let day = $03 ; program does not
use date, date, month, year
let date = $22
let month = $03
let year = $12
let blinky = 000000 ; 010000 would
Enable output at 1Hz blink rate.
000000 is no blink
writei2c 0,(seconds, minutes, hours,
day, date, month, year, blinky)
pause 50
#endrem
'/\ /\ /\ /\ Un_REM THESE LINES
(ABOVE) IF SETTING UP A NEW RTC /\
/\ /\ /\
; POWER ON SELF TEST. Send all three
meters to FULL Scale and back to 0
'NOTE: pwmduty hour_meter, w7
---->> w7 ranges from 0 to 400 to
move meter from 0VDC to 2VDC
for w7 = 400 to 0 step -1' pwmduty
needs a (W)ord var, not a (B)yte var
pwmduty hour_meter, w7 'adjust
PWM Duty from 100% to 0%
pwmduty minute_meter, w7
pwmduty second_meter, w7
next w7
main:
if temp_switch = 1 then
do ' while hour_set = 1 or minute_set
= 1 then 'if main buttom and H or M
set button pushed then
pwmduty hour_meter, 400 ' move all
meters to full scale to allow trimmer
adjust. Do 0 meter adjust 1st with
power off.
pwmduty minute_meter, 400
pwmduty second_meter, 400
loop while hour_set = 1 or minute_set
= 1
end if ' temp_switch = 1
if temp_switch = 1 and hour_set = 0
and minute_set = 0 then
do 'while temp_switch is pressed
gosub DisplayTemp
loop while temp_switch = 1 and
hour_set = 0 and minute_set = 0
end if
'read the RTC and display the time
readi2c 0, (seconds, minutes, hours,
day, date, month, year, blinky)
pause 10
'\/ \/ \/ \/ \/ SECONDS SECONDS
SECONDS \/ \/ \/ \/ \/
;Convert the Seconds from the RTC to
Base10 and update the meter
if temp_switch = 0 and minute_set =
1 and hour_set = 1 then 'all pressed.
Seconds to $00
gosub Seconds_set
end if
Ones_digi = seconds & 0x0F ' zero
out the top four bits
Tens_Digi = seconds & 0xF0 ' zero
out the lower four bits
Tens_Digi = Tens_Digi / 2 ' each
divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.
Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to
the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift
the Base10 value to Tens place
seconds = Tens_Digi + Ones_Digi
'complete. Now $ss is ss (in Base10)
' Update the seconds meter with a
w9 value of 0 to 400
w7 = seconds * 677 / 100 ;
(400/59=6.77) scale 0-59 seconds to
0-400 for PWM
pwmduty second_meter, w7
'/\ /\ /\ /\ SECONDS END /\ /\ /\ /\
/\ /\ /\
'\/ \/ \/ \/ MINUTES MINUTES
MINUTES \/ \/ \/ \/ \/
if temp_switch = 0 and minute_set =
1 and hour_set = 0 then 'if
temp_switch and M is pressed then
add on minute
gosub Minutes_set
end if
;Convert the Minutes from the RTC to
Base10 and update the meter
Ones_digi = minutes & 0x0F ' zero
out the top four bits
Tens_digi = minutes & 0xF0 ' zero
out the lower four bits
Tens_Digi = Tens_Digi / 2 ' each
divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.
Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to
the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift
the Base10 value to Tens place
minutes = Tens_Digi + Ones_Digi
'complete. Now $mm is mm (in
Base10)
'Update the minutes meter with a w9
value of 0 to 400
If minute_set = 0 then 'dont update if
we are setting the minutes. Should
correct this in Minutes_set routine
w7 = minutes * 677 / 100 ;
(400/59=6.77) scale 0-59 minutes to
0-400 for PWM
pwmduty minute_meter, w7
end if
'/\ /\ /\ /\ /\ MINUTES END /\ /\ /\ /\
/\
'\/ \/ \/ \/ \/ HOURS HOURS HOURS
\/ \/ \/ \/
if temp_switch = 0 and minute_set =
0 and hour_set = 1 then 'if
temp_switch and M is pressed then
add on minute
gosub Hours_set
end if
;Convert the Hours from the RTC to
Base10 and update the meter
Ones_digi = hours & 0x0F ' zero out
the top four bits
Tens_digi = hours & 0xF0 ' zero out
the lower four bits
Tens_Digi = Tens_Digi / 2 ' each
divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.
Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to
the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift
the Base10 value to Tens place
hours = Tens_Digi + Ones_Digi
'complete. Now $hh is hh (in Base10)
if hours > 12 then
hours = hours - 12
end if
if hours = 0 then
hours = 12
end if
' Update the hours meter with a w9
value of 0 to 400
w7 = hours * 3636 ; (400/11 = 36.36)
scale 1 to 12 hours to 0-400 for PWM
w7 = w7 - 3636 'subtract y interceot
to start PCM at 0 to 1 o'clock.
w7 = w7 / 100 'scale 1 to 12 hours to
0-400 for PWM
pwmduty hour_meter, w7
'/\ /\ /\ /\ /\ HOURS END /\ /\ /\ /\
/\
goto main
DisplayTemp:
readtemp temp_sensor,
CthermoValue
w7 = CthermoValue * 677 / 100
'(400/59=6.77) scale C to 0-400 for
PWM
pwmduty minute_meter, w7 'C (raw)
in the minutes meter)
'Convert C to F
FthermoValue = 9 * CthermoValue / 5
+ 32
w7 = FthermoValue * 364 ; (400/11 =
36.36) scale 10 to 120F to 0-400 for
PWM
w7 = w7 - 3636 'subtract y interceot
to start PCM at 0 to 10F
w7 = w7 / 100 'scale 0-400 for PWM
pwmduty hour_meter, w7 '(F (x10) on
the hours meter
'Convert C to K
KthermoValue = CthermoValue + 273
w7 = KthermoValue / 10
w7 = w7 * 677 / 100
pwmduty second_meter, w7 'Kelvin
*100 on the seconds meter
return 'DisplayTemp
Seconds_Set:
seconds = $00
writei2c 0,(seconds, minutes, hours,
day, date, month, year, blinky)
pause 50
w7 = seconds * 677 / 100 ;
(400/59=6.77) scale 0-59 seconds to
0-400 for PWM
pwmduty second_meter, w7
return 'Seconds_set
Minutes_Set:
readi2c 0, (seconds, minutes, hours,
day, date, month, year, blinky)
;Convert the Minutes from the RTC to
Base10 and update the meter
Ones_digi = minutes & 0x0F ' zero
out the top four bits
Tens_digi = minutes & 0xF0 ' zero
out the lower four bits
Tens_Digi = Tens_Digi / 2 ' each
divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.
Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to
the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift
the Base10 value to Tens place
minutes = Tens_Digi + Ones_Digi
'complete. Now $mm is mm (in
Base10)
minutes = minutes + 1
if minutes > 59 then
minutes = 0
end if
'convert base10 minutes to BCD here
then write new minute value to RTC
Ones_Digi = minutes // 10
Tens_Digi = minutes - Ones_Digi
Tens_Digi = Tens_Digi / 10
Tens_Digi = Tens_Digi * 2 ' shift the
lower right bits
Tens_Digi = Tens_Digi * 2 ' to the
upper left.
Tens_Digi = Tens_Digi * 2
Tens_Digi = Tens_Digi * 2
Tens_Digi = Tens_Digi OR Ones_Digi
'OR function on the two values to get
8 bit BDC
'Now Ten_digi = minutes in packed
BCD. Just using Tens_Digi as a temp
var
writei2c 0,(seconds, Tens_Digi, hours,
day, date, month, year, blinky)
pause 50
'Update the minutes meter with a w9
value of 0 to 400
w7 = minutes * 677 / 100 ;
(400/59=6.77) scale 0-59 minutes to
0-400 for PWM
pwmduty minute_meter, w7
pause 500
return ' Minutes_Set
Hours_Set: 'HOURS SET WORKS
PERFECT
readi2c 0, (seconds, minutes, hours,
day, date, month, year, blinky)
;Convert the Hours from the RTC to
Base10 and update the meter
Ones_digi = hours & 0x0F ' zero out
the top four bits
Tens_digi = hours & 0xF0 ' zero out
the lower four bits
Tens_Digi = Tens_Digi / 2 ' each
divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.
Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to
the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift
the Base10 value to Tens place
hours = Tens_Digi + Ones_Digi
'complete. Now $hh is hh (in Base10)
hours = hours + 1
if hours > 12 then
hours = hours - 12
end if
if hours = 0 then
hours = 12
end if
if hours > 9 then
if hours = 10 then
hours = $10
end if
if hours = 11 then
hours = $11
end if
if hours = 12 then
hours = $12
end if
end if
writei2c 0,(seconds, minutes, hours,
day, date, month, year, blinky)
pause 50
;Convert the Hours from the RTC to
Base10 and update the meter
Ones_digi = hours & 0x0F ' zero out
the top four bits
Tens_digi = hours & 0xF0 ' zero out
the lower four bits
Tens_Digi = Tens_Digi / 2 ' each
divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.
Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to
the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift
the Base10 value to Tens place
hours = Tens_Digi + Ones_Digi
'complete. Now $hh is hh (in Base10)
' Update the hours meter with a w9
value of 0 to 400
w7 = hours * 3636 ; (400/11 = 36.36)
scale 1 to 12 hours to 0-400 for PWM
w7 = w7 - 3636 'subtract y interceot
to start PCM at 0 to 1 o'clock.
w7 = w7 / 100 'scale 1 to 12 hours to
0-400 for PWM
pwmduty hour_meter, w7
pause 1000
return ' Hours_Set |
评分
-
2
查看全部评分
-
|