📄 test.asm
字号:
JMP CHECK_COMMON ;扫描公共子程序
;再扫描按键1
CHECK_KEY1:
LDI KEY_FLAG,00H ;CLEAR KEY_FLAG 清除AD电压变化大于1.25V的次数
LDI GEN_REG_ADCH,00H ;AN1通道
LDI GEN_REG_LED,1101B
JMP CHECK_COMMON ;扫描公共子程序
;再扫描按键2
CHECK_KEY2:
LDI KEY_FLAG,00H ;CLEAR KEY_FLAG 清除AD电压变化大于1.25V的次数
LDI GEN_REG_ADCH,00H ;AN2通道
LDI GEN_REG_LED,1011B
JMP CHECK_COMMON ;扫描公共子程序
;再扫描按键3
CHECK_KEY3:
LDI KEY_FLAG,00H ;CLEAR KEY_FLAG 清除AD电压变化大于1.25V的次数
LDI GEN_REG_ADCH,03H ;AN2通道
LDI GEN_REG_LED,0111B
JMP CHECK_COMMON ;扫描公共子程序
;再扫描按键4
CHECK_KEY4:
LDI KEY_FLAG,00H ;CLEAR KEY_FLAG 清除AD电压变化大于1.25V的次数
LDI GEN_REG_ADCH,04H ;AN2通道
LDI GEN_REG_LED,1110B
JMP CHECK_COMMON ;扫描公共子程序
;再扫描按键5
CHECK_KEY5:
LDI KEY_FLAG,00H ;CLEAR KEY_FLAG 清除AD电压变化大于1.25V的次数
LDI GEN_REG_ADCH,05H ;AN2通道
LDI GEN_REG_LED,1101B
JMP CHECK_COMMON ;扫描公共子程序
;再扫描按键6
CHECK_KEY6:
LDI KEY_FLAG,00H ;CLEAR KEY_FLAG 清除AD电压变化大于1.25V的次数
LDI GEN_REG_ADCH,06H ;AN2通道
LDI GEN_REG_LED,1011B
JMP CHECK_COMMON ;扫描公共子程序
;再扫描按键7
CHECK_KEY7:
LDI KEY_FLAG,00H ;CLEAR KEY_FLAG 清除AD电压变化大于1.25V的次数
LDI GEN_REG_ADCH,07H ;AN2通道
LDI GEN_REG_LED,0111B
JMP CHECK_COMMON ;扫描公共子程序
;扫描公共子程序
CHECK_COMMON:
CALL AD_CHECK ;AD多次检测子程序,输出1为触发,0为未触发
BA0 END_PROCESS ;结束返回子程序
JMP ERR_STA ;否则错误处理
;********** AD扫描子程序 START********************************
;********************************************************
;AD_CHECK:AD采样扫描
; 采样次数-1,若次数为0则采样结束,否则继续采样
; 设置对应红外灯发射,AD通道设置,延时,等待采样完成,存储采样数据2
; 设置红外灯关闭,AD通道设置,延时,等待采样完成,存储采样数据1
; 将数据1和数据2比较,若两数差值大于预设定的常量,则KEY_FLAG加1
; 进行下一次采样
; 采样结束,将KEY_FLAG与预定的数值比较,若大,则表示按键触发
;
;********************************************************
AD_CHECK:
SBIM AD_8_COUNT, 01H ;AD_8_COUNT - 1送AD_8_COUNT,根据检测次数来判断是否结束
BAZ JUMP_OUT ;若AD_8_COUNT = 0,则跳到JUMP_OUT,结束
;********* 灯亮状态 ***********
LDA KEY_PORT_FLAG ;读取KEY_PORT_FLAG值,确定扫描哪个按键
BAZ SET_PORTE ;设置PORTE端口红外输出
LDI PORTE,0FH ;熄灭PORTE口的红外灯
LDA GEN_REG_LED ;设置PORTF端口红外输出,将GEN_REG4->ACC
STA PORTF,0H ;设置PORTF输出,点亮红外灯
JMP SET_ADCH ;跳至SET_ADCH
SET_PORTE: ;设置PORTF口,点亮红外,熄灭PORTE口红外
LDI PORTF,0FH ;熄灭PORTF口的红外灯
LDA GEN_REG_LED ;设置PORTE端口红外输出,将GEN_REG4->ACC
STA PORTE,00H ;设置PORTE输出,点亮红外灯
;设置AD通道
SET_ADCH: ;设置ADCH
LDI GEN_REG1,1000B ;设置开始位
OR GEN_REG_ADCH,0H ;GEN_REG_ADCH是用来通道,1000B OR CHNNAL
STA ADCH ;ADCH = 1000B |ANX
CALL DELAY ;延时
CALL DELAY
LDI ADCON, 1010B ;AD开始转换,时间 330*tOSC 改成50*tosc
NOP
;等待AD转换完
WAIT1_LOOP: ;等待
NOP
LDA ADCON ;查询GO/DONE 位,判断A/D 转换是否完成。
BA3 WAIT1_LOOP
LDA ADRESH ;灯亮情况, A/D 中断发生,存储转换灯亮结果。
STA AD_LIGHT_DATA2H ;高位-〉AD_LIGHT_DATA2H
LDA ADRESL
STA AD_LIGHT_DATA2L ;低位-〉AD_LIGHT_DATA2L
;********* 灯灭状态,读取按键AD值 *******
LDI PORTE,0FH ;PORTE 高,灯灭状态
LDI PORTF,0FH ;PORTF 高,灯灭
CALL DELAY ;延时
CALL DELAY
NOP
LDI ADCON, 1010B ;AD开始转换,时间 330*tOSC 改成50*tosc
NOP
WAIT2_LOOP:
NOP
LDA ADCON ;查询GO/DONE 位,判断A/D 转换是否完成。
BA3 WAIT2_LOOP
NOP
LDA ADRESH ;A/D 中断发生,存储转换灯灭结果。
STA AD_LIGHT_DATA1H ;存高位
LDA ADRESL
STA AD_LIGHT_DATA1L ;存低位
; *******数据处理部分**********
LDA AD_LIGHT_DATA2H ;AD_LIGHT_DATA2H -〉ACC
SUB AD_LIGHT_DATA1H, 0H;AD_LIGHT_DATA1H - AD_LIGHT_DATA2H =ACC
BC AD_COMP ;若AD_LIGHT_DATA1H>AD_LIGHT_DATA2H,转AD_COMP
JMP AD_CHECK ;返回AD_CHECK
;比较AD差值
AD_COMP: ;AD差值比较,若AD_TEMPH>2H,则可认为按键触发,KEY_FLAG ++
STA AD_TEMPH ;取差值
SBI AD_TEMPH,AD_COMP_HIGH ;(40H/FFH)*5V
BC FLAG_ADD ;CY =1,DIFF< 1.25V,GO NO_KEY
BAZ SUB_LOW
JMP AD_CHECK ;跳回,继续执行
SUB_LOW: ;低位值比较
LDA AD_LIGHT_DATA2L ;AD_LIGHT_DATA2L->ACC
SUB AD_LIGHT_DATA1L,0H ;AD_LIGHT_DATA1L-AD_LIGHT_DATA2L
BC COMP_LOW ;若AD_LIGHT_DATA1L大,则比较差值
JMP AD_CHECK ;否则跳回AD_CHECK
; 低位差值与常量
COMP_LOW:
STA AD_TEMPL ;存差值到AD_TEMPL
SBI AD_TEMPL,AD_COMP_LOW ;AD_TEMPL - 比较用的常量
BC FLAG_ADD ;若差值大于0EH,跳到标志+1子程序
JMP AD_CHECK ;否则跳回
;标志+1
FLAG_ADD:
ADIM KEY_FLAG,1H ;KEY_FLAG+1,触发标志位+1
JMP AD_CHECK ;返回AD_CHECK
; *******数据处理部分******************************************
;跳出该按键检测
JUMP_OUT: ;0FH次灯亮灯灭AD采集完成
LDA GEN_REG_AD_COUNT_VALUE ;将AD_COUNT_VALUE -->ACC
STA AD_8_COUNT ;ACC-> AD_8_COUNT
LDA GEN_REG_COMP_CONST ;送比较常数至ACC
SUB KEY_FLAG, 0H ;若KEY_FLAG >COMP_CONST次,则表示按键触发,
BC SET_ACC ;按键处理程序
LDI GEN_REG1,0H ;置ACC为0
RTNI ;返回
SET_ACC:
LDI GEN_REG1,1H ;置ACC为1
RTNI ;返回
;****************** AD_CHECK END ********************************
;=============================================================
;延时子程序(5ms)
DELAY:
LDI GEN_REG2,0
LDI GEN_REG3,0
DELAY2:
NOP ;
NOP
NOP
NOP
NOP
ADIM GEN_REG3,1
LDI GEN_REG1,0
ADCM GEN_REG2
BC $+2
JMP DELAY2
RTNI
;=============================================================
COMM_SERVER:
LDI IRQ,0000B
;写第1位
LDA OUT_FLAG
BA3 $+3
ANDIM COMM_BUF,1011B ;置0
JMP $+2
ORIM COMM_BUF,COMM_SDA ;置1
STA COMM_PORT ;SDA线置高
LDI TM0,01H ;时钟分频512
LDI TL0,0FH ;计数器低位
LDI TH0,03H ;计数器高位 FF-9F=60H*512us=50ms
LDI IE,0100B ;开定时器中断
LDI T0CON,0H ;系统时钟
;***** 定时器50ms开始 *****
CALL WAIT_HIGH
CALL WAIT_LOW
;写第2位
LDA OUT_FLAG
BA2 $+3
ANDIM COMM_BUF,1011B ;置0
JMP $+2
ORIM COMM_BUF,COMM_SDA ;置1
STA COMM_PORT ;SDA线置高
CALL WAIT_HIGH
CALL WAIT_LOW
;写第3位
LDA OUT_FLAG
BA1 $+3
ANDIM COMM_BUF,1011B ;置0
JMP $+2
ORIM COMM_BUF,COMM_SDA ;置1
STA COMM_PORT ;SDA线置高
CALL WAIT_HIGH
CALL WAIT_LOW
;写第4位
LDA OUT_FLAG
BA0 $+3
ANDIM COMM_BUF,1011B ;置0
JMP $+2
ORIM COMM_BUF,COMM_SDA ;置1
STA COMM_PORT ;SDA线置高
CALL WAIT_HIGH
CALL WAIT_LOW
;写OUT_FLAG反码第1位
LDA OUT_FLAG_DIFF
BA3 $+3
ANDIM COMM_BUF,1011B ;置0
JMP $+2
ORIM COMM_BUF,COMM_SDA ;置1
STA COMM_PORT ;SDA线置高
CALL WAIT_HIGH
CALL WAIT_LOW
;写OUT_FLAG反码第2位
LDA OUT_FLAG_DIFF
BA2 $+3
ANDIM COMM_BUF,1011B ;置0
JMP $+2
ORIM COMM_BUF,COMM_SDA ;置1
STA COMM_PORT ;SDA线置高
CALL WAIT_HIGH
CALL WAIT_LOW
;写OUT_FLAG反码第3位
LDA OUT_FLAG_DIFF
BA1 $+3
ANDIM COMM_BUF,1011B ;置0
JMP $+2
ORIM COMM_BUF,COMM_SDA ;置1
STA COMM_PORT ;SDA线置高
CALL WAIT_HIGH
CALL WAIT_LOW
;写OUT_FLAG反码第4位
LDA OUT_FLAG_DIFF
BA0 $+3
ANDIM COMM_BUF,1011B ;置0
JMP $+2
ORIM COMM_BUF,COMM_SDA ;置1
STA COMM_PORT ;SDA线置高
CALL WAIT_HIGH
CALL WAIT_LOW
OUT_COMM_SERVER:
LDI IE,0001B
RTNI
;等待高
WAIT_HIGH:
LDA COMM_PORT
BA3 $+2
JMP $-2
RTNI
;等待低
WAIT_LOW:
LDA COMM_PORT
BA3 $-1
RTNI
;超时处理程序
TO_SERVER:
LDI IRQ,0H ;清标志
LDI IE,0001B
JMP MAIN ;复位
INCLUDE INIT.ASM
INCLUDE SYS.ASM
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -