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

📄 io2acpl.asm

📁 HT46R47對AC過零信號進行檢測
💻 ASM
字号:
;;**********File Name: IO2ACPL.asm*******************
;;
;;---------------------------------------------------
;;Project Name: 		I/O to AC Power Line		|
;;Project No.:			VL2007050003				|
;;Author:				Jammas yang					|
;;Date:					2007/05/21					|
;;Version:				V0.0						|
;;													|
;;HT_IDE Version: 		V6.6 SP5					|
;;MCU Body:				HT46R47						|
;;---------------------------------------------------
;;
;;---------------------------------------------------
;;Mask Option:
;;---------------------------------------------------
;;VDD: 					5.0V						|
;Fsys: 					4MHz						|
;OSC: 					Crystal						|
;WDT: 					Enable						|
;WDT Clock Source: 		T1 (SYSTEM CLOCK/4)			|
;CLR WDT: 				One clear instruction		|
;Wake_Up PA.0-7: 		None-Wake-Up				|
;Pull-high PA: 			None-PULL-HIGH				|
;Pull-high PB: 			None-PULL-HIGH				|
;Pull-high Pd: 			None-PULL-HIGH				|
;PWM					Disable						|
;PA3 PFD				Disable						|
;LVR 					Enable						|
;LVR VOLTAGE			3.8V						|
;;---------------------------------------------------
	
;;================start include======================
.LISTINCLUDE

#INCLUDE HT46R47.INC

#define		RAM_SIZE		64		;;all general registers
#define		COUNT_60HZ		133		;;time count @60Hz
#define		COUNT_50HZ		160		;;time count @50Hz

;;================end of include=====================

;;********start variant define***********************
Gobal_variant .SECTION	'DATA'

acc_stack				DB 	?		;;to save special register acc
status_stack 			DB 	?		;;to save special register status

flag_055h				DB	?		;;reset flag1
flag_0aah				DB	?		;;reset flag2, secrurity
us						DB	?		;;us level time variant
ms						DB 	?		;;ms level time variant
second					DB	?		;;second level time variant for ZCD interval
phase_position			DB	?		;;0~160 for 50Hz, 0~133 for 60Hz.
									;;as to 50/60Hz, 160*2.25=360 degree, 133*2.7=360 degree
								
tmp_phase				DB	?		;;phase detection temporary variant
loop_index				DB	?		;;loop count
	
flag_first_zcd			DBIT		;;0 for first zero crossing, 1 for second zero crossing
flag_zcd_int			DBIT		;;flag of Zero crossing detecting
flag_zcd_rest			DBIT		;;flag of non-ZCD period
;;*********end of variant define*********************

;;================start code=========================
CODE_MAIN .SECTION AT 00H 'CODE'	
	JMP 	MAIN_START				;;jump to main code entrance

;;-----------int_isr()-------------------------------
	ORG 	004H					;;external interrupt entrance
	JMP		INT_ISR					;;jump to external interrupt subroutine
;;-----------end of int_isr()------------------------

;;-----------timer_isr()-----------------------------
	ORG 	008H					;;timer interrupt entrance
	JMP		TIMER_ISR				;;jump to timer interrupt subroutine
;;-----------end of timer_isr()----------------------

;;-----------ad_isr()--------------------------------
	ORG 	00CH					;;A/D conversion entrance, no used
	RETI
;;-----------end of ad_isr()-------------------------

;;-----------main()----------------------------------
MAIN_START:
	MOV		A,	flag_055h			;;check if flag1(content 55H) changed
	XOR		A,	55H
	SNZ		Z 
	JMP		COOL_RESTART			;;yes, jump to cool restart system
	MOV		A,	flag_0aah			;;check if flag2(content AAH) changed
	XOR		A,	0AAH
	SNZ		Z
	JMP		COOL_RESTART			;;yes, jump to cool restart system
	CALL	INIT_SPECIAL_REGISTERS	;;reset in normal operation, only reset special registers
	JMP 	MAIN_LOOP				;;jump to main_loop
	
COOL_RESTART:						;;reset when power on
	CALL INIT_SPECIAL_REGISTERS		;;reset special registers
	CALL INIT_GENERAL_REGISTERS		;;reset general registers
	
MAIN_LOOP:	
	CLR		WDT						;;clear Watching Dog Timer
	SZ		second					;;if time out
	JMP		main_loop				;;no, still waiting
	MOV		A,	1					;;yes, resetting ZCD interval = 1sec.
	MOV		second,	A
	SZ		flag_zcd_rest			;;if need to ZCD now
    JMP		$+4						;;yes, ZCD now
    CLR		PB						;;off all LEDs
    SET		flag_zcd_rest			;;no, set flag of non-ZCD period
	JMP		MAIN_LOOP				;;jump to main loop
    CLR		flag_zcd_rest			;;yes, clear flag of non-ZCD period
									;;zero crossing detecting right now
	SZ		flag_zcd_int			;;waiting for ZCD complete
	JMP		$-1						;;complete?, no, still waiting
	
	MOV		A,	phase_position		;;yes, check if Power Line frequency is 50HZ
	MOV		tmp_phase,	A			;;save to a temporary variant
	CLR		phase_position			;;Clear power line cycle count
	SUB		A,	COUNT_50HZ + 5		;;if within COUNT_50HZ +/-5
	SZ		C
	JMP		TO_OTHER_FREQUENCY		;;no, jump to next 60hz checking
	MOV		A,	tmp_phase
	SUB		A,	COUNT_50HZ - 5
	SNZ		C
	JMP		TO_60HZ_DETECTION		;;no, jump to next 60hz checking
	SET		Pb3						;;yes, 50HZ_LED on
	CLR		Pb2						;;yes, 60HZ_LED off
	CLR		tmp_phase
	JMP 	MAIN_LOOP				;;jump to main_loop
	
TO_60HZ_DETECTION:					;;Check if Power Line frequency is 60HZ
	MOV		A,	tmp_phase
	SUB		A,	COUNT_60HZ + 5
	SZ		C
	JMP		TO_OTHER_FREQUENCY		;;no, jump to other case handling code
	MOV		A,	tmp_phase
	SUB		A,	COUNT_60HZ - 5
	SNZ		C
	JMP		TO_OTHER_FREQUENCY		;;no, jump to other case handling code
	CLR		Pb3						;;yes, 50HZ_LED off
	SET		Pb2						;;yes, 60HZ_LED on
	CLR		tmp_phase
	JMP 	MAIN_LOOP				;;jump to main_loop
	
TO_OTHER_FREQUENCY:
	CLR		PB						;;off all LEDs
	JMP 	MAIN_LOOP				;;jump to main_loop
	
;;-----------end of main()---------------------------
	
;;-----------int_isr()-------------------------------
INT_ISR:
	MOV 	acc_stack,	A			;;save ACC data
   	MOV 	A,	Status
	MOV 	status_stack,	A		;;save Status registor data
    
    SET		flag_zcd_int			;;set flag of ZCD interrupt
    SZ		flag_first_zcd			;;if 1st entering interrupt
    JMP		TO_2ND_INT				;;no, jump to 2nd interrupt handling code
    CLR		phase_position			;;yes, clear time count within power line cycle
    SET		flag_first_zcd			;;set 1st entering interrupt flag
    SET		pa4						;;just for testing purpose*
    JMP		EXIT_INT_ISR			;;exit external interrupt subroutine
    
TO_2ND_INT:
	CLR		pa4						;;just for testing purpose*
    CLR		flag_first_zcd			;;clear 1st entering interrupt flag
    CLR		flag_zcd_int			;;clear flag of ZCD interrupt
    
EXIT_INT_ISR:    
	MOV 	A,	status_stack		;;restore status registor data
	MOV 	STATUS,	A
	MOV 	A,	acc_stack			;;restore ACC data
	RETI
;;-----------end of int_isr()------------------------

;;-----------timer_isr()-----------------------------
TIMER_ISR:
	MOV 	acc_stack,	A			;;save ACC data
   	MOV 	A,	STATUS
	MOV 	status_stack,	A    	;;save Status registor data

	SZ		flag_zcd_int			;;if already openning ZCD interrupt?
	INC		phase_position			;;yes, time count add one
	SDZ 	us						;;us --, us == 0?
	JMP 	EXIT_TIME_ISR			;;no, exit timer interrupt
	MOV 	A, 32					;;yes, reset us = 32
	MOV 	us,	A	
	
	SDZ		ms						;;ms --, ms == 0?
	JMP 	EXIT_TIME_ISR			;;no, exit timer interrupt
	MOV 	A, 250					;;yes, reset ms = 250
	MOV 	ms, A
	SZ		second					;;second == 0?
	DEC 	second					;;no, second --
	
EXIT_TIME_ISR:
	MOV 	A,	status_stack		;;restore status registor data
	MOV 	STATUS,	A
	MOV 	A,	acc_stack			;;restore ACC data

	RETI
;;-----------end of timer_isr()----------------------

;;-----------init_special_registers()----------------
INIT_SPECIAL_REGISTERS:
	MOV		A,	00100000b			;;all PA port output besides PA5
	MOV 	PAC,	A
	CLR		PBC						;;all PB port output
	CLR		PDC						;;all PD port output
	CLR		PA						;;clear all PA port
	CLR		PB						;;clear all PB port
	MOV		A,	10011010b			;;setting timer mode, falling edge trigger, 1/4 Fsys
	MOV		TMRC,	A				;;save to TMRC
	MOV		A,	131					;;timer interrupt interval: 125us=(256-131)*(1/4Mhz/4) 
	MOV 	TMR,	A				;;save to TMR
	CLR		INTC					;;disable all interrupts
	SET		EMI						;;enable main interrrupt
	SET		ETI						;;enable Timer interrrupt
	SET		EEI						;;yes, need to open ZCD interrupt
	
	RET
;;-----------end of init_special_registers()---------
	
;;-----------init_general_registers()----------------
INIT_GENERAL_REGISTERS:
	MOV 	A,	RAM_SIZE			;;clear all general reigstors
	MOV		loop_index,	A
	MOV		A,	OFFSET status_stack	;;point to RAM first address [40H]
	MOV		MP0,	A
	CLR		R0						;;clear the RAM cell content to zero
	INC		MP0						;;point to the next one
	SDZ		loop_index				;;all cells complete?
	JMP		$-3						;;no, to clear the next RAM cell
	
	MOV		A, 055H
	MOV		flag_055h,	A			;;written reset flag1 (55H)
	MOV		A, 0AAH
	MOV 	flag_0aah,	A			;;written reset flag2 (AAH)
	
	MOV 	A,	32
	MOV		us,	A					;;let us = 32
	MOV		A,	250
	MOV		ms,	A					;;let ms = 250
    MOV		A,	1					;;ZCD interval = 1sec.
    MOV		second,	A				;;let second = 1sec.
    
	CLR		phase_position			;;clear time count of ZCD
	CLR		flag_first_zcd			;;clear first ZCD flag
	CLR		flag_zcd_int			;;clear start-up ZCD flag
    SET		flag_zcd_rest			;;flag of non-ZCD period
	
	RET
;;-----------end of init_general_registers()---------
	
	END								;;main code ending
;;================end of code========================

;;**********end of IO2ACPL.asm***********************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -