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

📄 traffic light firmware.asm

📁 交通灯汇编程序
💻 ASM
字号:
	CHIP	SN8P2604
//{{SONIX_CODE_OPTION
	.Code_Option	Noise_Filter	Disable
	.Code_Option	Reset_Pin	Reset
	.Code_Option	Watch_Dog	Disable		; Disable Watchdog
	.Code_Option	High_Clk	4M_X'tal	; Crystal/Resonator: 2Mhz~10Mhz
	.Code_Option	Fcpu		#2     ; Fcpu = High_Clk/4
	.Code_Option	Security	Disable
//}}SONIX_CODE_OPTION
.DATA
	DLY1	DS	02H
	DLY2	DS	03H	;延时程序暂存器
	TIMER00	EQU	04H	;tc1中断计数器
	TIMER01	EQU	05H	;t0中断计数器
	S_CNT	EQU	06H
	S_BIT	EQU	07H
	DISP1	EQU	0AH
	DISP2	EQU	0BH
	DISP3	EQU	0CH
	DISP4	EQU	0DH
	N_L	EQU	10H	;北边显示器低位
	N_H	EQU	11H	;北边显示器高位
	E_L	EQU	12H	;东边显示器低位
	E_H	EQU	13H	;东边显示器高位
.CODE
	ORG	00H
	JMP	MAIN
	ORG	08H
	JMP	CYC
	ORG	10H
;************************************
;主程序
;************************************
MAIN:
	CALL	INIT_IO
	CALL	INIT_DATA
	CALL	INIT_TIMER
	CALL	INIT_TC0
START:
	CALL	DATA_SHOW
	CALL	SCAN
	JMP	START
;************************************
;扫描
;************************************
SCAN:
	MOV	A,#04H
	MOV	S_CNT,A
	MOV	A,#11110111B
	MOV	S_BIT,A
	CLR	Y
	MOV	A,#0AH
	MOV	Z,A
SCAN_LP:
	MOV	A,@YZ
	MOV	P2,A
	MOV	A,S_BIT
	MOV	P5,A
	CALL	DELAY
	DECMS	S_CNT
	JMP	@F
	RET
@@:
	INCMS	Z
	NOP
	B0BSET	FC
	RRCM	S_BIT
	MOV	A,#0FFH
	MOV	P2,A
	JMP	SCAN_LP
;************************************
;显示
;************************************
DATA_SHOW:
	MOV	A,E_L
	AND	A,#00001111B	;取出秒的低四位元来做数据转换
	CALL	BCD_DISP
	MOV	DISP1,A		;把显示的值送到disp1

	MOV	A,E_H
	AND	A,#00001111B	;取出秒的高四位元来做数据转换
	CALL	BCD_DISP
	MOV	DISP2,A		;把显示的值送到disp2

	MOV	A,N_L
	AND	A,#00001111B	;取出秒的低四位元来做数据转换
	CALL	BCD_DISP
	MOV	DISP3,A		;把显示的值送到disp3

	MOV	A,N_H
	AND	A,#00001111B	;取出秒的高四位元来做数据转换
	CALL	BCD_DISP
	MOV	DISP4,A		;把显示的值送到disp4
	RET
;************************************
;TC1中断
;************************************
MY_IRQ:
	PUSH
	B0BTS1	FTC1IRQ
	JMP	EXIT_IRQ	;检查中断
	B0BCLR	FTC1IRQ
	MOV	A,#61
	MOV	TC1C,A		;设定每50ms中断一次
	DECMS	TIMER00
	JMP	EXIT_IRQ
	MOV	A,#20
	MOV	TIMER00,A
//判断是否为00
CHECK00:
	MOV	A,#00H
	CMPRS	A,N_H		;yes,比较北边高位是否为00	
	JMP	NORMAL00	;no,减一秒

	MOV	A,#00H
	CMPRS	A,N_L
	JMP	CHECK42
	JMP	CHECK18		;比较高位低位是否为00,用以隔开设定17s,正常计数。
CHECK18:
	MOV	A,#18H
	CMPRS	A,P1
	JMP	CHECK14		;n=第一步,设定17s计数
	JMP	SET03		;判断此时led显示是否为18h,y=第二步,03--00
CHECK14:
	MOV	A,#14H
	CMPRS	A,P1
	JMP	SET17
	JMP	SET20
CHECK42:
	MOV	A,#42H
	CMPRS	A,P1			
	JMP	NORMAL00
	
	MOV	A,#04H
	CMPRS	A,N_L
	JMP	NORMAL00
	JMP	SET031
SET17:
	MOV	A,#18H
	MOV	P1,A
	MOV	A,#08
	MOV	N_L,A
	MOV	A,#01
	MOV	N_H,A	;北边赋值18
	JMP	NORMAL00
SET03:
	MOV	A,#14H
	MOV	P1,A
	MOV	A,#03
	MOV	N_L,A
	MOV	A,#00
	MOV	N_H,A	;北边赋值03
	JMP	NORMAL00
SET20:
	MOV	A,#42H	
	MOV	P1,A
	MOV	A,#01
	MOV	N_L,A
	MOV	A,#02
	MOV	N_H,A
	JMP	NORMAL00
SET031:
	MOV	A,#22H
	MOV	P1,A
	MOV	A,#04
	MOV	N_L,A
	MOV	A,#00
	MOV	N_H,A	;北边赋值03
	JMP	NORMAL00
;*********************************
;TO中断
;*********************************
INTT0:
	PUSH
	B0BTS1	FT0IRQ
	JMP	EXIT_IRQ	;检查中断

	B0BCLR	FT0IRQ
	MOV	A,#61
	MOV	T0C,A		;设定每50ms中断一次
	DECMS	TIMER01
	JMP	EXIT_IRQ
	MOV	A,#20
	MOV	TIMER01,A
CHECKE00:
	MOV	A,#00H
	CMPRS	A,E_H
	JMP	NORMAL01
	MOV	A,#00H
	CMPRS	A,E_L
	JMP	NORMAL01	;检查00,用以隔开东边计数
CHECKE18:
	MOV	A,#18H
	CMPRS	A,P1
	JMP	CHECKE14
	JMP	SETE20		;检查led是否为18h,设定东边为20s
CHECKE14:
	MOV	A,#14H
	CMPRS	A,P1
	JMP	CHECKE42
	JMP	SETE03		;检查led是否为14h,设定东边为03s
CHECKE42:
	MOV	A,#42H
	CMPRS	A,P1
	JMP	CHECKE22
	JMP	SETE17		;检查led是否为14h,设定东边为17s
CHECKE22:
	MOV	A,#22H
	CMPRS	A,P1
	JMP	NORMAL01
	JMP	SETE03		;检查led是否为22h,设定东边为03s
SETE20:
	MOV	A,#01
	MOV	E_L,A
	MOV	A,#02
	MOV	E_H,A
	JMP	NORMAL01
SETE03:
	MOV	A,#03
	MOV	E_L,A
	MOV	A,#00
	MOV	E_H,A
	JMP	NORMAL01	
SETE17:
	MOV	A,#08
	MOV	E_L,A
	MOV	A,#01
	MOV	E_H,A
	JMP	NORMAL01
;*********************************
;北边减一秒
;*********************************
NORMAL00:
	MOV	A,N_L		;北边秒低位
	SUB	A,#01		;减1
	MOV	N_L,A

	MOV	A,N_L	
	CMPRS	A,#0FFH		;比较是否为FF
	JMP	EXIT_IRQ	;no,跳出中断
	MOV	A,#09		;yes,赋值09
	MOV	N_L,A

	MOV	A,N_H		;北边秒高位
	SUB	A,#01		;减1
	MOV	N_H,A

	CMPRS	A,#0FFH		;比较是否为FF
	JMP	EXIT_IRQ	;no,跳出中断
	MOV	A,#09		;yes,赋值09
	MOV	N_H,A

	JMP	EXIT_IRQ	;跳出中断
;*********************************
;南边减一秒
;*********************************
NORMAL01:
	MOV	A,E_L		;东边秒低位
	SUB	A,#01		;减1
	MOV	E_L,A	

	MOV	A,E_L	
	CMPRS	A,#0FFH		;比较是否为FF
	JMP	EXIT_IRQ	;no,跳出中断
	MOV	A,#09		;yes,赋值09
	MOV	E_L,A

	MOV	A,E_H		;东边秒高位
	SUB	A,#01		;减1
	MOV	E_H,A
	CMPRS	A,#0FFH		;比较是否为FF
	JMP	EXIT_IRQ	;no,跳出中断
	MOV	A,#09		;yes,赋值09
	MOV	E_H,A
	JMP	EXIT_IRQ	;跳出中断
;*********************************
;选择中断
;*********************************
CYC:
	B0BTS1	FTC1IEN
	JMP	@F
	B0BTS0	FTC1IRQ
	JMP	MY_IRQ
@@:
	B0BTS1	FT0IEN
	JMP	EXIT_IRQ
	B0BTS0	FT0IRQ
	JMP	INTT0
	RET
;*********************************
;初始化
;*********************************
INIT_IO:
	MOV	A,#0FFH
	MOV	P1M,A
	MOV	P2M,A
	MOV	P5M,A
	MOV	P2,A
	CLR	P1
	RET
INIT_DATA:
	CLR	DLY1
	CLR	DLY2
	CLR	N_L
	CLR	N_H
	CLR	E_L
	CLR	E_H
	RET
;初始化TC1
INIT_TIMER:
	B0BCLR	FTC1IEN		;关闭中断
	B0BCLR	FTC1ENB
	MOV	A,#00000100B
	MOV	TC1M,A		;设定tc1 clock=Fcpu/256
	MOV	A,#61
	MOV	TC1C,A		;设定每50ms中断一次
	MOV	A,#20
	MOV	TIMER00,A

	B0BSET	FTC1IEN
	B0BCLR	FTC1IRQ
	B0BSET	FTC1ENB
	B0BSET	FGIE
	RET
;初始化T0
INIT_TC0:
	B0BCLR	FT0IEN		;关闭中断
	B0BCLR	FT0ENB
	MOV	A,#00000100B
	MOV	T0M,A		;设定tc1 clock=Fcpu/256
	MOV	A,#61
	MOV	T0C,A		;设定每50ms中断一次
	MOV	A,#20
	MOV	TIMER01,A

	B0BSET	FT0IEN
	B0BCLR	FT0IRQ
	B0BSET	FT0ENB
	B0BSET	FGIE
	RET
EXIT_IRQ:
	POP
	RETI
;********************************
;查表
;********************************
BCD_DISP:
	B0MOV	Y,#TABLE$M
	B0MOV	Z,#TABLE$L
	ADD	A,Z
	MOV	Z,A
	MOVC
	RET
;********************************
;数据表
;********************************
TABLE:
	DW	01C0H
	DW	01F9H
	DW	01A4H
	DW	01B0H
	DW	0199H
	DW	0192H
	DW	0182H
	DW	01F8H
	DW	0180H
	DW	0190H
DELAY:
	MOV	A,#60H
	MOV	DLY1,A

	MOV	A,#04H
	MOV	DLY2,A
@@:
	DECMS	DLY1
	JMP	@B
	DECMS	DLY2
	JMP	@B
	RET
	ENDP	
	
	

⌨️ 快捷键说明

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