?? hwgyjnkg.asm
字號:
.def nightLightTimer = r25 ;Zero if vacant, else timeout in 16-line-cycle units
.def threshold = r26 ;Occupancy sensor trip points, for negative-going edge
.def pulseTimer = r27 ;Times PIR pulse edges, in line cycles
.def newSample = r28 ;Latest ADC sample for occupancy detection
.def eepAdrs = r29 ;Address in EEPROM for next operation (Read/Write)
.def counter = r30 ;Also ZL, Used to index into SRAM (registers)
.def ignoreTimer = r31 ;Also ZH, If non-zero, the number of line cycles that must
; elapse before the occupancy sensor input is again
; considered valid (used to ignore transients introduced
; by relay switching)
;
; Bits in the "status" register:
;
.equ fStaUnused0 = 0 ;** Unused and available **
.equ fStaUnused1 = 1 ;** Unused and available **
.equ fStaUnused2 = 2 ;** Unused and available **
.equ fStaSwitchLoad = 3 ;Set if relay is to be switched to opposite state
.equ fStaFirstSeen = 4 ;Set if first valid pulse has been seen from PIR
.equ fStaProgram = 5 ;Program Mode selected if high
.equ fStaMode0 = 6 ;Operating mode, encoded as two-bit field
.equ fStaMode1 = 7
;
;-------------------------------------
;
; Microcontroller Part Programming Information
;
; The ATtiny15L part used for this firmware is designed to be programmed in-circuit,
; using an SPI interface. See the Atmel documentation for details.
;
; The programming sequence should be as follows:
;
; 1. Verify that the part is erased.
;
; 2. Read the factory oscillator calibration value from location $00 of the
; device signature information, and program it into the low byte of the
; last word in the flash memory of the device (i.e., byte location 03FE hex).
;
; 3. Program the flash memory of the part with the appropriate file.
;
; 4. Program the fuse bits as follows:
;
; BODLEVEL = Unprogrammed (Selects 4.0VDC brownout level)
; BODEN = Unprogrammed (Enables brownout detector)
; SPIEN = Programmed (Enables SPI programming)
; RSTDISBL = Programmed (Disables RESET function of Pin 1)
; CKSEL_1 = Programmed (Selects fast startup clock, with
; CKSEL_0 = Programmed brownout detector enabled)
;
; 5. Program both lock bits (1 & 2) to prohibit later examination of the code.
;
;-------------------------------------
;
; Occupancy Sensor Parameters
;
; The following parameters control the operation of the PIR occupancy sensor
; detection algorithm.
;
.equ NOISE_OFFSET = 8 ;Offset from noise peak to threshold = 0.1V
.equ MIN_THRESH = 26 ;Min threshold (max sensitivity) @ +/- 0.50V
.equ MAX_THRESH = 61 ;Max threshold (min sensitivity) @ +/- 1.2V
.equ HOLD_THRESH = 87 ;Hold-on threshold @ +/- 1.7V
.equ MIN_PULSE = 3 ;Min pulse width = 2 line cycles (0.05 seconds)
.equ MIN_WIDTH = 30 ;Minimum pulse spacing = 0.5 seconds
.equ MAX_WIDTH = 120 ;Maximum pulse spacing = 2.0 seconds
.equ PIR_CENTER = 102 ;Centerline of PIR ADC waveform = 2.0VDC
.equ MAX_PIR = PIR_CENTER*2
.equ DEF_NOISE = (MIN_THRESH - NOISE_OFFSET)
;
;-------------------------------------
;
; Oscillator Calibration
;
; The main internal oscillator of the ATtiny15 is tunable, and an ideal value for
; this tuning is chosen on a part-by-part basis by the factory. This value can be
; found in the high-order byte of address $000 of the signature address space. Because
; the firmware cannot directly read this area, the value is copied, during in-circuit-
; programming of the micro, into the highest word of the flash memory (low byte of $01FF).
;
; We use Timer 1, driven with a divider of 128 from the calibrated oscillator, to measure
; AC line cycle durations and delays. We can therefore calculate the expected half-cycle
; duration, for a 60Hz line, as:
;
; HALFCYC = (1600000 / 128) / 60 / 2 = 104.16666...
;
.equ HALFCYC = 104
.equ QUARTCYC = 52
.equ FULLCYC = 208
;
;-------------------------------------
;
; Relay Timing Default Values
;
; The following constants define the default delay values, timed from the positive-
; to-negative half-cycle boundary, to the point at which the relay coil should be
; energized or deenergized, targetting the closure or opening of the contacts to
; occur just before the next positive-to-negative zero crossing (this due to the
; fact that the event can only be directly observed during the positive half-cycle
; of the AC waveform). All timing is done in Timer1 ticks, which as documented above
; is in 80uS increments.
;
.equ ON_DEFAULT = QUARTCYC ;Assume close time < 12.5mS
.equ OFF_DEFAULT = HALFCYC ;Assume open time < 8.3mS
.equ BACKOFF = 2 ;If late, move backwards by 160uS
;
;-------------------------------------
;
; Relay Switching Transient Lockout
;
; When the relay switches on or off, transients may be coupled into the occupancy
; sensor circuitry that can cause false trips. To mask these events, the firmware
; ignores all occupancy events for a preset number of line cycles after each relay
; switching operation.
;
.equ IGNORE_CYC = 90 ;Ignore all events for 1.5 seconds
;
;-------------------------------------
;
; Button Debouncing
;
; The front panel button is debounced by capturing its state once every line cycle,
; and maintaining a history of the last eight samples. A valid press is designated
; as three consecutive "down" samples after an "up" sample. The number of bits
; considered in this process can be modified by changing the following two constants:
;
.equ DEBOUNCE_MASK = $0F ;Look at four most recent samples
.equ DEBOUNCE_PRESS = $08 ;Accept as a press one UP followed by three DOWN
.equ DEBOUNCE_RELEASE = $01 ;Accept as a release three DOWN followed by one UP
.equ HOLD_CYC = 30 ;Recognize button as held after 0.5 seconds
;
;-------------------------------------
;
; EEPROM Address Assignments
;
; The following variables are allocated storage in the non-volatile EEPROM area:
;
.equ EE_VALID = $5A ; Bit pattern indicating that unit has passed the
; manufacturing test sequence
.equ EE_ERASED = $FF ; Bit pattern if virgin unit (EEPROM erased)
.eseg
eeValid: .db EE_ERASED ;Set to EE_VALID when manufacturing test
; is completed successfully; if <> EE_VALID,
; indicates virgin unit.
eeMode: .db MODE1 ;Operating Mode
eeOnDelay: .db ON_DEFAULT ;Timer1 reload value for Relay On delay
eeOffDelay: .db OFF_DEFAULT ;Timer1 reload value for Relay Off delay
eeTimeouts:
eeTimeoutM1: .dw M1_TIMEOUT
eeTimeoutM2: .dw M2_TIMEOUT
eeTimeoutM3: .dw M3_TIMEOUT
eeTimeoutM4: .dw M4_TIMEOUT
eeTimeoutM5: .dw M5_TIMEOUT
eeModePatterns:
.dw 0b1100000000000000 ;Mode 1 (index=0)
.dw 0b1101100000000000 ;Mode 2 (index=1)
.dw 0b1101101100000000 ;Mode 3 (index=2)
.dw 0b1101101101100000 ;Mode 4 (index=3)
.dw 0b1101101101101100 ;Mode 5 (index=4)
;
; Manufacturing Test Patterns
;
; The nightlight flash sequences reported by the manufacturing test code are
; stored after the normal mode patterns, so that they can be invoked using the
; same supporting subroutines.
;
.dw 0b1000000010000000 ;Test failure #1 (index=5)
.dw 0b1010000010100000 ;Test failure #2 (index=6)
.dw 0b1010100010101000 ;Test failure #3 (index=7)
.dw 0b1010101010101010 ;Test passed (index=8)
;
;-------------------------------------
.cseg
;----- Interrupt Vectors -----------------------;
;
; The WN firmware does not presently use any interrupts; therefore, we can save
; flash memory space by knowing that they are not used. They are documented, in
; order, below, in case a future modification will require their use.
;
.org 0
rjmp Start ;Reset vector
;== reti ;INT0 (should not occur)
;== reti ;Pin Change (should not occur)
;== reti ;Timer1 Compare Match A (should not occur)
;== reti ;Timer1 Overflow (should not occur)
;== reti ;Timer0 Overflow (should not occur)
;== reti ;EEPROM Ready (should not occur)
;== reti ;Analog Comparator (should not occur)
;== reti ;ADC Conversion Complete (should not occur)
;----- Reset Entry Point -----------------------;
;
; This entry is reached under three conditions:
;
; - Initial power-on, or power-on from a "cold" condition, or
;
; - Brown-out reset, if Vcc drops below threshold (approx. 4.0VDC), or
;
; - Watchdog Timeout, which can occur if the AC line drops for a significant number
; of line cycles, or a static hit derails the micro's PC
;
; In any case, the complete state of the device is reinitialized, and the load
; is returned to an OFF state, and any automatic operation is cancelled until the
; next time that the pushbutton is pressed.
Start: in temp0,MCUSR ; Determine cause of Reset, and
sbrs temp0,WDRF ; if caused by a Watchdog reset,
rjmp StartEEP2 ; we must write down latest values
ldi eepAdrs,eeOnDelay ; of the relay timings into the
rcall ReadEEPROM ; nonvolatile memory (EEPROM),
cp temp0,onDelay ; if they have changed.
breq StartEEP1
ldi eepAdrs,eeOnDelay
mov temp0,onDelay
rcall WriteEEPROM
StartEEP1:
rcall ReadEEPROM
cp temp0,offDelay
breq StartEEP2
ldi eepAdrs,eeOffDelay
mov temp0,offDelay
rcall WriteEEPROM
StartEEP2:
clr ZH ; Initialize all of RAM (registers)
ldi ZL,30 ; to zeroes for predictable behavior
Start1: dec ZL
st Z,ZH
brne Start1
ldi ZH,HIGH(FactoryOscCal*2)
ldi ZL,LOW(FactoryOscCal*2)
lpm ; Read correct oscillator calibration
out OSCCAL,result ; and setup oscillator
ldi button,$FF ; Show button not pressed
ldi temp0,DEF_NOISE ; Preset noise integral
mov noiseH,temp0
ldi temp0,MIN_THRESH ; And start at maximum sensitivity
mov threshold,temp0
ldi temp0,PORTB_INIT ; Condition I/O port
out PORTB,temp0
ldi temp0,DDRB_INIT
out DDRB,temp0
ldi temp0,ADMUX_OCCUP ; Setup A/D converter
out ADMUX,temp0
ldi temp0,ADCSR_INIT ; Start ADC operation
out ADCSR,temp0
sbi ACSR,ACD ; Disable comparator to save power
ldi eepAdrs,eeMode ; Initialize mode,
rcall ReadEEPROM
mov mode,temp0
rcall ReadEEPROM ; and relay timing delays
mov onDelay,temp0
rcall ReadEEPROM
mov offDelay,temp0
wdr ; Reset watchdog timer,
ldi temp0,WDTCR_INIT ; then start it, using an approximate
out WDTCR,temp0 ; timeout of 0.4 seconds
ldi eepAdrs,eeValid ; Determine if this is a virgin unit,
rcall ReadEEPROM ; which should occur only in manufacturing
cpi temp0,EE_ERASED ; test.
brne MainLoop ; If EQ, not virgin unit.
;
; Manufacturing Tests
; -------------------
;
; The following sequence is executed on the initial, virgin unit power-up. It validates
; certain accessible hardware parameters, and switches the relay to validate its operation.
; The results of the testing are reported in the nightlight LEDs as a flash pattern.
;
rcall Delay16Cycles ;Wait to allow power supply to stabilize
ldi temp0,MAX_MODE+1 ;Assume initial test failure
mov mode,temp0
;
; Validate zero-crossing input
;
ldi temp0,TCCR1_INIT ;Ensure that zero-cross signal goes high
out TCCR1,temp0 ;within less than one line-cycle
MfgTest1:
sbic PINB,fZeroCross ;While the zero cross signal is low
rjmp MfgTest2 ;we check the timing, and
in temp1,TCNT1 ;if it exceeds a line cycle,
cpi temp1,FULLCYC ;we declare error type 1
brlo MfgTest1
rjmp MfgTestX
MfgTest2:
out TCNT1,zero ;Then clear the timer, and verify that
MfgTest3:
sbis PINB,fZeroCross ; the signal is seen as high
rjmp MfgTest4
in temp1,TCNT1
cpi temp1,FULLCYC
brlo MfgTest3 ;If not seen low, report error type 1
rjmp MfgTestX
MfgTest4:
inc mode ;Advance to error type 2
ldi temp0,(1<<PSR1) ;And reset the prescaler counter
out SFIOR,temp0 ;as well, to increase predictability
out TCNT1,zero ;Finally, verify line cycle length to
MfgTest5:
sbis PINB,fZeroCross ; make sure that the oscillator calibration
rjmp MfgTest5 ; has been properly programmed.
in temp1,TCNT1
cpi temp1,HALFCYC-3
brlo MfgTestX ;If < 8.08mS, report error type 2
cpi temp1,HALFCYC+4
brsh MfgTestX ;If > 8.56mS, report error type 2
;
; Validate relay operation
;
inc mode ;Advance to error type 3
MfgTest6:
in temp1,TCNT1 ;Wait until middle of positive half-cycle
cpi temp1,HALFCYC+QUARTCYC ; to validate relay sense signal
brne MfgTest6
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -