📄 ballot.asm
字号:
;模拟抽签程序(在P1.0接上按钮)
NUMB DATA 2FH ;总签数保存单元。
RANDS EQU 30H ;“签筒”存放首址。
OUTS EQU 50H ;抽签结果存放首址。
ORG 0000H
LJMP TEST
ORG 100H
TEST: MOV NUMB,#20 ;总签数=20
LCALL RAND
STOP: LJMP STOP
RAND: MOV R0,#RANDS ;指向“签筒”位置。
MOV R7,NUMB ;取总签数。
MOV A,#1 ;从一号签开始。
SETUP: MOV @R0,A ;生成1~n个签号,将其投入“签筒”。
INC A
INC R0
DJNZ R7,SETUP
MOV R1,#OUTS ;抽签结果存放地址初始化。
SETB P1.0 ;将P1.0设置为输入状态,准备进行抽签。
LOOP: MOV R3,#0 ;“数字转盘”初始化。
LOOP1: MOV A,R3
INC A ;转动一格。
CJNE A,NUMB,LOOP2 ;转动格数超过当前剩下签数否?
CLR A ;返回到第一格。
LOOP2: MOV R3,A
ADD A,#RANDS ;加上“签筒”位置。
MOV R0,A ;得到当前对应签号位置。
MOV A,@R0 ;将当前对应的签号读出。
LCALL DISP ;显示当前对应的签号。
MOV A,P1 ;检查按键状态。
JB ACC.0,LOOP1 ;未按键,继续转动。
MOV A,R3 ;发现按下按键,取当前的相对位置。
ADD A,#RANDS ;加上“签筒”位置。
MOV R0,A ;得到抽中的签号位置。
MOV A,@R0 ;输出这次抽签结果。
MOV @R1,A
INC R1
MOV A,NUMB ;判断这次抽签位置后面存在的签数。
SETB C
SUBB A,R3
MOV R7,A
JZ LOOP4 ;这次抽签位置在最后。
MOV A,R1 ;保存输出指针。
PUSH ACC
MOV A,R0
MOV R1,A
INC R1
LOOP3: MOV A,@R1 ;移动后面各签,将中签号从“签筒”中删除。
MOV @R0,A
INC R0
INC R1
DJNZ R7,LOOP3
POP ACC ;恢复输出指针。
MOV R1,A
LOOP4: MOV A,P1 ;等待按键释放。
JNB ACC.0,LOOP4
MOV R6,#10 ;延时去抖动。
MOV R7,#0
LOOP5: DJNZ R7,LOOP5
DJNZ R6,LOOP5
MOV A,P1
JNB ACC.0,LOOP4 ;等待按键真正释放,防止连击现象。
LOOP6: MOV A,P1 ;显示冻结,直到再次按下按键。
JB ACC.0,LOOP6
LOOP7: MOV R6,#10 ;延时去抖动。
MOV R7,#0
LOOP8: DJNZ R7,LOOP8
DJNZ R6,LOOP8
MOV A,P1
JNB ACC.0,LOOP7 ;等待按键真正释放,开始抽下一个签。
DJNZ NUMB,LOOP ;剩下签数减一,直到全部抽完。
RET
DISP: NOP ;显示模块(根据实际电路编写)。
NOP
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -