star 发表于 2012-8-21 14:59:35

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]
查看完整版本: A PIC16F84A Alarm Clock