📄 io.asm
字号:
.include "2407.h" ;头文件,2407寄存器的设置
.include "intx.h" ;头文件,中断向量表的设置
.include "varx.h" ;头文件,变量的定义
.include "conx.h" ;头文件,常量的定义
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.def _c_int0
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
IOSFT_REG .usect ".data0",1 ;显示数据移位寄存器
IO_COUNT .usect ".data0",1 ;延时计数寄存器
IO_DATA .usect ".data0",1 ;I/O临时数据缓冲区
LEDXS .usect ".data0",1 ;LED显示的数据
LEDFLAG .usect ".data0",1 ;LED显示标志 寄存器
K1FLAG .usect ".data0",1 ;K1 标志寄存器
KEYDATA .usect ".data0",1 ;读得键盘值存放寄存器
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;(2)主程序
.text
_c_int0
CALL SYSINIT ;调系统初始化程序
CALL KEYLEDINIT ;调键盘和LED初始化程序
LDP #DP_USER ;指向0280h~0300h区
SPLK #01H,IOSFT_REG ;寄存器和标志初始化
SPLK #00H,IO_COUNT
SPLK #001H,IO_DATA
SPLK #001H,LEDXS
SPLK #00H,LEDFLAG ;LEDFLAG.0=1表示 K1,K2,K3 按下
;LEDFLAG.0=0表示 K4 按下
SPLK #01H,K1FLAG
CLRC INTM ;开总中断
LOOP: CALL KEY ;调键盘程序,即扫描键盘
LDP #DP_USER
BIT LEDFLAG,15
BCND LEDBD1,TC
LACL IO_COUNT
SUB #03E8H
BCND WAIT,LEQ ;判10 s延时到否
LEDBD1: SPLK #00H,IO_COUNT
LDP #DP_PF2
LACL PFDATDIR
OR #0404H ;IOPF2=1
SACL PFDATDIR ;开74HC273片选信号
LDP #DP_USER
LACL LEDXS
OR #0FF00H ;IOPB口为输出方式
LDP #DP_PF2
SACL PBDATDIR ;送要显示的数据到IOPB口
LACL PFDATDIR
AND #0FFFBH ;IOPF2=0
SACL PFDATDIR ;关74HC273片选信号
LDP #DP_USER
BIT LEDFLAG,15
BCND LEDBD2,TC
LACL LEDXS
SFL
SACL LEDXS
LACL IOSFT_REG
SFL
SACL IOSFT_REG
BIT IOSFT_REG,BIT8 ;判是否循环完一次
BCND LOOP1,TC
B WAIT
LOOP1: LDP #DP_USER
SPLK #01H,IOSFT_REG ;赋初值
LEDBD2: LACL IO_DATA
SACL LEDXS
WAIT: NOP
B LOOP
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;(3)系统初始化程序
SYSINIT:
SETC INTM
CLRC SXM
CLRC OVM
CLRC CNF ;B0区被配置为数据空间
LDP #DP_PF1 ;指向7000h~7080h区
SPLK #81FEH,SCSR1 ;时钟4倍频,CLKIN=6 M,CLKOUT=24 M
SPLK #0E8H,WDCR ;不使能WDT
LDP #0
SPLK #02H,IMR ;使能中断优先级INT2
SPLK #0FFFFh,IFR ;清中断标志
LDP #DP_EVA ;指向7400h~7480h区
SPLK #80H,EVAIMRA ;使能T1PINT 中断
SPLK #0FFFFh,EVAIFRA ;清EVA中断标志
SPLK #0,GPTCONA
SPLK #0EA6H,T1PR ;使定时器每10 ms产生一次中断
SPLK #0,T1CNT
SPLK #0164CH,T1CON ;设置通用定时器1
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;(4)键盘和发光二极管初始化程序
KEYLEDINIT:
LDP #DP_PF2
LACL MCRC
AND #083FFH ;IOPF2,IOPF[3~6] 配置为一般的I/O口
SACL MCRC
LACL MCRA
AND #000FFH ;IOPB[0~7] 配置为一般的I/O口
SACL MCRA
LACL PFDATDIR
OR #0400H ;IOPF2为输出方式
AND #08787H ;IOPF[3~6] 为输入方式
SACL PFDATDIR
LACL PBDATDIR
OR #0FF00H ;IOPB[0~7] 为输出方式
SACL PBDATDIR
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;(5)键盘程序
KEY:
CALL READKEY ;调读键程序
LACL KEYDATA
BCND KEYRET,EQ ;ACC=0?
CALL KEYDELAY ;延时消抖动
CALL READKEY ;再一次读键值
LACL KEYDATA
BCND KEYRET,EQ
LDP #DP_USER ;判断按键情况
BIT KEYDATA,15
BCND KEY2,NTC
CALL K1 ;功能键按下
B KEYRET
KEY2: BIT KEYDATA,14
BCND KEY3,NTC
CALL K2 ;"+"键按下
B KEYRET
KEY3: BIT KEYDATA,13
BCND KEY4,NTC
CALL K3 ;移位键按下
B KEYRET
KEY4: BIT KEYDATA,12
BCND KEYRET,NTC
CALL K4 ;确认键按下
KEYRET: LACL KEYDATA
AND #0FFF0H ;清读取的键值寄存器
SACL KEYDATA
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;(6)读键子程序
READKEY:
LDP #DP_PF2
LACL PFDATDIR ;取出键值PFDATDIR.3~PFDATDIR.6
RPT #2
SFR ;右移3位
OR #0FFF0H ;屏蔽高4位(用到4个键)
CMPL
LDP #DP_USER
SACL KEYDATA ;存放键值
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;(7)用软件延时30mS消抖动
KEYDELAY:
LACC #6000
KEYD1: SUB #1
RPT #80
NOP
BCND KEYD1,NEQ
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;(8)4个键子程序
K1: ;功能键子程序
READK1: CALL KEYDELAY
CALL READKEY
LDP #DP_USER ;判断按键 K1 是否松开
BIT KEYDATA,15
BCND READK1,TC
LDP #DP_USER ;可扩展成16个或更多分支
SPLK #01H,LEDFLAG ;关闭LED左移标志,即LED对同一个数不刷新
BIT K1FLAG,15 ;K1FLAG存放K1按键的次数相对应的位值
BCND GN_KEY1,TC ;即K1FLAG=01,表示按了1次
BIT K1FLAG,14 ;K1FLAG=02,表示按了2次
BCND GN_KEY2,TC ;K1FLAG=04,表示按了3次
BIT K1FLAG,13
BCND GN_KEY3,TC
BIT K1FLAG,12
BCND GN_KEY4,TC
BIT K1FLAG,11
BCND GN_KEY5,TC
BIT K1FLAG,10
BCND GN_KEY6,TC
BIT K1FLAG,9
BCND GN_KEY7,TC
BIT K1FLAG,8
BCND GN_KEY8,TC
B K1_RET
GN_KEY1:SPLK #01H,IO_DATA
B K1_LOOP1
GN_KEY2:SPLK #11H,IO_DATA
B K1_LOOP1
GN_KEY3:SPLK #03H,IO_DATA
B K1_LOOP1
GN_KEY4:SPLK #033H,IO_DATA
B K1_LOOP1
GN_KEY5:SPLK #05H,IO_DATA
B K1_LOOP1
GN_KEY6:SPLK #55H,IO_DATA
B K1_LOOP1
GN_KEY7:SPLK #07H,IO_DATA
B K1_LOOP1
GN_KEY8:SPLK #77H,IO_DATA
B K1_LOOP1
K1_LOOP1:LACL K1FLAG
SFL
SACL K1FLAG
BIT K1FLAG,7
BCND K1_LOOP2,TC
B K1_RET
K1_LOOP2:SPLK #01H,K1FLAG
K1_RET: NOP
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
K2: ;"+"键子程序
READK2: CALL KEYDELAY
CALL READKEY
LDP #DP_USER ;判断按键 K2 是否松开
BIT KEYDATA,14
BCND READK2,TC
SPLK #01,LEDFLAG ;关闭LED左移标志,即LED对同一个数不刷新
LACL IO_DATA
ADD #1
SACL IO_DATA
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
K3: ;移位键子程序
READK3: CALL KEYDELAY
CALL READKEY
LDP #DP_USER ;判断按键 K3 是否松开
BIT KEYDATA,13
BCND READK3,TC
LDP #DP_USER
SPLK #01H,LEDFLAG
LACL IO_DATA
SFR
SACL IO_DATA
BCND K3_LOOP1,NC ;C=1 则IO_DATA+80h
LACL #80H
ADD IO_DATA
K3_LOOP1:SACL IO_DATA
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
K4: ;确认键子程序
READK4: CALL KEYDELAY
CALL READKEY
LDP #DP_USER ;判断按键 K4 是否松开
BIT KEYDATA,12
BCND READK4,TC
LDP #DP_USER
SPLK #00H,LEDFLAG ;恢复LED左移标志
SPLK #01H,IO_DATA
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;(9)中断程序
GISR2: ;优先级INT2中断人口
;保护现场
LDP #0E0H
LACC PIVR,1 ;读取外设中断向量寄存器(PIVR),并左移一位
ADD #PVECTORS ;加上外设中断入口地址
BACC ;跳到相应的中断服务子程序
T1GP_ISR: ;通用定时器1中断入口
LDP #DP_USER
LACL IO_COUNT
ADD #1
SACL IO_COUNT
;恢复现场
CLRC INTM ;开总中断,因为一进中断就自动关闭总中断
RET
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;(10)假中断程序
PHANTOM
KICK_DOG ;复位看门狗
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -