⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hwgyjnkg.asm

📁 红外感应节能开关
💻 ASM
📖 第 1 页 / 共 4 页
字号:
.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 + -