📄 io2acpl.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 + -