📄 controllogic.asm
字号:
;==============================================================================
; Clock Control Logic
;------------------------------------------------------------------------------
; Notes:
;
; The 16F74 does not have any EEPROM so the memory area of the RTC is used to
; store alarm times.
;
; The RTC is forced into 12-Hour mode during setup. The alarm times are
; recorded as 12-Hour times in the same pattern used by the RTC chip so they
; can be directly compared.
;==============================================================================
; Revision History:
;
; 2005-02-16 Added alarm sounding and silencing states.
;
; 2005-02-06 Initial version
;------------------------------------------------------------------------------
include ../pic.inc
include ../lib/dallas1307.inc
include ../lib/config.inc
include display.inc
include hardware.inc
global BeginClocking
extern DS1307Tx
extern DS1307Rx
extern HexLedPattern
extern I2C_REGISTER
extern I2C_REGCOUNT
extern SCRATCH
; The RTC memory registers used to hold alarm times.
RTC_AL_DAY_MIN equ h'10'
RTC_AL_DAY_HOUR equ h'11'
RTC_AL_SAT_MIN equ h'12'
RTC_AL_SAT_HOUR equ h'13'
RTC_AL_SUN_MIN equ h'14'
RTC_AL_SUN_HOUR equ h'15'
; Define aliases for LED segments
SA equ SEGMENT_A
SB equ SEGMENT_B
SC equ SEGMENT_C
SD equ SEGMENT_D
SE equ SEGMENT_E
SF equ SEGMENT_F
SG equ SEGMENT_G
;==============================================================================
; Declare storage area for the current time and the alarm settings.
udata
SECONDS res 1
MINUTES res 1
HOURS res 1
DAY res 1
DATE res 1
MONTH res 1
YEAR res 1
CONTROL res 1
CHANGED res 1
AL_DAY_MIN res 1
AL_DAY_HOUR res 1
AL_SAT_MIN res 1
AL_SAT_HOUR res 1
AL_SUN_MIN res 1
AL_SUN_HOUR res 1
;==============================================================================
code
; Read the alarm time settings from the RTC eeprom
BeginClocking:
banksel I2C_REGISTER
movlw RTC_CONTROL
movwf I2C_REGISTER
movlw .1
movwf I2C_REGCOUNT
bankisel SCRATCH
movlw CONTROL
movwf FSR
movlw h'10'
movwf CONTROL
lcall DS1307Tx
banksel I2C_REGISTER
movlw RTC_AL_DAY_MIN
movwf I2C_REGISTER
movlw .6
movwf I2C_REGCOUNT
bankisel AL_DAY_MIN
movlw AL_DAY_MIN
movwf FSR
lcall DS1307Rx
;------------------------------------------------------------------------------
; Most the time the clock is simply displaying the current time and waiting for
; either an alarm to be triggered or a button to be pressed
WaitForEvent: call UpdateTime
call TestForAlarm
skpnc
goto AlarmTriggered
AlarmSilent:
call AlarmOff
call WaitForChange
skpz
call HandleSwitches
goto WaitForEvent
;------------------------------------------------------------------------------
; If an alarm is triggered then flash the display and lamp while sounding the
; buzzer until a button is pressed.
WaitForQuiet: call UpdateTime
call TestForAlarm
skpc
goto AlarmSilent
AlarmTriggered:
call AlarmPulse
btfsc CTRL,CTRL_BUZZ
goto AlarmSteady
movlw h'ff'
movwf SEG1
movwf SEG2
movwf SEG3
movwf SEG4
AlarmSteady:
call WaitForChange
andlw h'07'
skpnz
goto WaitForQuiet
call WaitForRelease
;------------------------------------------------------------------------------
; Waits until the alarm period has been passed before returning to the normal
; wait loop.
WaitForUpdate: call UpdateTime
call TestForAlarm
skpc
goto AlarmSilent
call AlarmOff
call WaitForChange
skpz
call HandleSwitches
goto WaitForUpdate
;==============================================================================
; Wait until either one or more switches have been pressed or the 1Hz pulse has
; changed
WaitForChange:
banksel PORTD ; Read current 1Hz state
movf PORTD,W
banksel SCRATCH
movwf SCRATCH ; .. and store
ScanSwitches:
banksel PORTE ; Read the current state of the switch
movf PORTE,W ; .. inputs
call WaitForSync ; Wait for next interrupt
xorwf PORTE,W ; Re-read switches and detect changes
andlw (1<<SW_R)|(1<<SW_H)|(1<<SW_M)
skpz
return ; Return if any changed
banksel PORTD ; Re-read the 1HZ input
movf PORTD,W
banksel SCRATCH
xorwf SCRATCH,W ; Has it changed?
andlw (1<<HZ)
skpnz
goto ScanSwitches ; No, re-check the switches
movlw 0
return
;==============================================================================
; Returns with C=1 if the active alarm matches the current time.
TestForAlarm:
call GetAlarmFile
movwf FSR
banksel MINUTES
movf MINUTES,W
subwf INDF,W
skpz
goto ClearCarry
incf FSR,F
movf HOURS,W
subwf INDF,W
skpz
goto ClearCarry
SetCarry:
setc
return
ClearCarry:
clrc
return
; Returns the register index corresponding to the alarm that should be used for
; today.
GetAlarmFile:
bankisel AL_DAY_MIN
banksel DAY
movf DAY,W
addlw -1
skpnz
retlw AL_SUN_MIN
addlw -6
skpnz
retlw AL_SAT_MIN
retlw AL_DAY_MIN
;==============================================================================
; If the 1Hz signal is high then sound the alarm else turn it off.
AlarmPulse:
banksel PORTD
btfsc PORTD,HZ
goto AlarmOn
; Turn the control bits for the buzzer and lamp off so the next interrupt will
; silence the alarm.
AlarmOff:
banksel CTRL
bcf CTRL,CTRL_BUZZ
bcf CTRL,CTRL_LAMP
return
; Turn the control bits for the buzzer and lamp on so the next interrupt will
; sound the alarm.
AlarmOn:
banksel CTRL
bsf CTRL,CTRL_BUZZ
bsf CTRL,CTRL_LAMP
return
;==============================================================================
; Read the current time from the RTC and generate the values to update the
; display on the next interrupt.
UpdateTime:
banksel I2C_REGISTER
movlw RTC_SECONDS
movwf I2C_REGISTER
movlw .7
movwf I2C_REGCOUNT
bankisel SECONDS
movlw SECONDS
movwf FSR
call DS1307Rx
bankisel MINUTES
movlw MINUTES
movwf FSR
goto ShowTime
;==============================================================================
HandleSwitches:
banksel SCRATCH
movwf SCRATCH
btfsc SCRATCH,SW_R
goto AdjustTime
btfsc SCRATCH,SW_H
goto HandleDayDate
btfsc SCRATCH,SW_M
goto HandleMonthYear
return
;------------------------------------------------------------------------------
AdjustTime:
call WaitForRelease
banksel CHANGED ; Clear the change value flag
clrf CHANGED
banksel SECONDS ; Reset the seconds
clrf SECONDS
banksel CTRL ; Turn on the lamp
bsf CTRL,CTRL_LAMP
TimeAdjust:
bankisel MINUTES ; Point the FSR at the MINUTES
movlw MINUTES
movwf FSR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -