A PIC16F84A Alarm Clock
本帖最后由 star 于 2012-8-21 15:10 编辑'
' PIC16F84A ALARM CLOCK
'
'
' feel free to use this code at your own risks
'
' targetPIC16F84A, 16 Mhz crystal
' HS clock, no watchdog.
'
'
'
program alarmClock
'
' if you are using COMMON CATHODE LED display, uncomment this definition.
' if you are using COMMON ANODE LED display, comment this definition.
'
'#define CATHODE_COMMUNE
symbolLUNDI = 0 ' monday
symbolMARDI = 1 ' thuesday
symbolMERCREDI = 2 ' wednesday
symbolJEUDI = 3 ' thursday
symbolVENDREDI = 4 ' friday
symbolSAMEDI = 5 ' saturday
symbolDIMANCHE = 6 ' sunday
symbolLMMJV = 7 ' from monday to friday included
'
' alarm definitions, to be changed on your needs
'
symbolNBALARM = 16 ' number of programmed alarms
const alarmTable as byte = (
' JOUR HEURE MINUTEDUREE (secondes, 59 maxi)
' DAY HOUR MINUTEDURATION (in seconds, max is 59)
LUNDI, 8, 30, 10,
LUNDI, 12, 30, 10,
LUNDI, 14, 00, 10,
LUNDI, 16, 30, 10,
MARDI, 8, 30, 10,
MARDI, 12, 30, 10,
MARDI, 14, 00, 10,
MARDI, 16, 30, 10,
JEUDI, 8, 30, 10,
JEUDI, 12, 30, 10,
JEUDI, 14, 00, 10,
JEUDI, 16, 30, 10,
VENDREDI, 8, 30, 10,
VENDREDI, 12, 30, 10,
VENDREDI, 14, 00, 10,
VENDREDI, 16, 30, 10
)
dim maxcount as word ' number of TMR0 overflow per second
dim scaler as word ' RTC scaler
dim jj as byte ' day of week, 0 is monday
dim hh as byte ' hour
dim mn as byte ' min
dim ss as byte ' sec
dim digiled as byte ' 4 x 7 segment table
dim digit as byte ' number of current digit to be displayed
dim dp as byte ' decimal point
dim key as byte ' key code
dim alarm as byte ' alarm flag
'
' the ISR works as real time clock
'
sub procedure interrupt
dim i as byte
'
' count time
'
scaler = scaler + 1
if scalermaxcount
then
scaler = 0
inc(ss)
if ss = 60
then
ss = 0
inc(mn)
if mn = 60
then
mn = 0
inc(hh)
if hh = 24
then
hh = 0
inc(jj)
if jj = 8
then
jj = 1
end if
end if
end if
end if
end if
'
' LED display
'
#ifdef CATHODE_COMMUNE
PORTA = PORTA and $f0
TRISA = $0f
key = PORTA
TRISA = 0
PORTB = 0
#else
PORTA = PORTA or $0f
TRISA = $0f
key = PORTA
key = not(key)
TRISA = 0
PORTB = $ff
#endif
key = key and $07
digit = digit + 1
if digit3
then
digit = 0
i = $01
else
i = $01digit
end if
#ifdef CATHODE_COMMUNE
PORTB = digiled
PORTA = PORTA or i
#else
PORTB = digiled
PORTB = not(PORTB)
PORTA = PORTA and not(i)
#endif
INTCON.T0IF = 0
end sub
'
' converts digit to 7 segment
'
sub function intTo7seg(dim n as byte) as byte
select case n
case 0result = $3F
case 1result = $06
case 2result = $5B
case 3result = $4F
case 4result = $66
case 5result = $6D
case 6result = $7D
case 7result = $07
case 8result = $7F
case 9result = $6F
end select
end sub
'
' select a value with keys
' value is pointed to by v, display char s as header, maximum value is max
'
sub procedure setValue(dim v as ^byte, dim s as byte, dim max as byte)
digiled = s
digiled = 0
while 1
if key.0
then
inc(v^)
if(v^max)
then
v^ = 0
end if
end if
if key.1
then
if(v^ = 0)
then
v^ = max
else
dec(v^)
end if
end if
if key.2
then
Delay_ms(50)
while key.2
wend
Delay_ms(50)
scaler = 0
ss = 0
return
end if
digiled = intTo7seg(v^10)
digiled = intTo7seg(v^ mod 10)
delay_ms(300)
wend
end sub
'
' program entry
'
main
dim i as byte
'
' init variables
'
dp = 0
hh = 0
mn = 0
ss = 0
jj = 0
maxcount = 15625
'
' init IO
'
PORTA = 010000
TRISA = 000000
PORTB = 0
TRISB = $00
'
' init interrupts
'
INTCON = 100000
OPTION_REG = 011000
Delay_ms(50)
'
' clock adjustment
'
setValue(@hh, 116, 23)
setValue(@mn, 55, 59)
setValue(@jj, 14, 6)
'
' forever loop
'
while true
if key
then
'
' display day and seconds (what fordon't remember !)
'
digiled = intTo7seg(jj)
digiled = 0
digiled = intTo7seg(ss10)
digiled = intTo7seg(ss mod 10)
else
'
' display hours and minutes
'
if hh10
then
digiled = 0
digiled = intTo7seg(hh)
else
digiled = intTo7seg(hh10)
digiled = intTo7seg(hh mod 10)
end if
digiled = intTo7seg(mn10)
digiled = intTo7seg(mn mod 10)
end if
'
' blinks semicolon (or decimal point)
'
if scalermaxcount2
then
dp.1 = 1
else
dp.1 = 0
end if
'
' set decimal points
'
digiled.7 = dp.0
digiled.7 = dp.1
digiled.7 = dp.2
digiled.7 = dp.3
'
' check for alarm condition
'
alarm = 0
for i = 0 to (NBALARM - 1)4
if ((alarmTable = jj) or ((alarmTable = LMMJV) and (jjSAMEDI)))
and (alarmTable = hh)
and (alarmTable = mn)
and (alarmTabless)
then
inc(alarm)
end if
next i
if alarm
then
'
' set alarm
'
dp.3 = 1
PORTA.4 = 0
else
'
' clear alarm
'
dp.3 = 0
PORTA.4 = 1
end if
wend
end.
页:
[1]