基于8051的两位倒计时计时器启停按钮功能实现求助
基于8051的两位倒计时计时器启停按钮功能实现求助
嘿,我看了你这段8051汇编的倒计时代码,要给它加上P3.2端口的启停按钮功能,确实得调整原有的线性执行逻辑——毕竟原来的代码是一路跑到底,没留出处理按键输入的空间。咱们一步步来解决这个问题:
核心思路说明
要实现启停/暂停/继续的功能,需要三个关键环节:
- 用一个状态寄存器记录当前计时器是「暂停」还是「运行」状态
- 给按键加消抖处理,避免机械抖动导致的误触发
- 把原有的线性倒计时逻辑改成循环检测结构,在每个计时周期前后检查按键状态
修改后的完整代码
$MOD51 ; This includes 8051 definitions for the Metalink assembler ; 状态定义:R3=0 代表暂停,R3=1 代表运行 STATE_PAUSE EQU 0 STATE_RUN EQU 1 ; 全局变量:存储当前倒计时的十位和个位数值 ; R4 = 十位数字(初始9),R5 = 个位数字(初始9) start: MOV R3, #STATE_PAUSE ; 初始状态设为暂停 MOV R4, #9 ; 初始化十位为9 MOV R5, #9 ; 初始化个位为9 LCALL UPDATE_DISPLAY ; 显示初始值99 main_loop: LCALL CHECK_BUTTON ; 每次循环先检查按键状态 CJNE R3, #STATE_RUN, main_loop ; 如果是暂停状态,循环等待按键 ; 运行状态:执行倒计时逻辑 LCALL WAIT ; 等待一个计时周期 LCALL DECREMENT_COUNT ; 递减倒计时数值 LCALL UPDATE_DISPLAY ; 更新显示 SJMP main_loop ; 回到主循环 ; --------------------------- ; 按键检测与状态切换子程序 ; 按键接P3.2,低电平有效(可根据硬件调整) ; --------------------------- CHECK_BUTTON: JB P3.2, BUTTON_EXIT ; 如果按键没按下(高电平),直接退出 LCALL SHORT_DELAY ; 消抖延迟 JB P3.2, BUTTON_EXIT ; 再次检查,确认真的按下 ; 等待按键松开,避免持续触发 WAIT_RELEASE: JNB P3.2, WAIT_RELEASE LCALL SHORT_DELAY ; 松开时也消抖 ; 切换状态 CPL R3 BUTTON_EXIT: RET ; --------------------------- ; 倒计时数值递减子程序 ; --------------------------- DECREMENT_COUNT: MOV A, R5 CJNE A, #0, DEC_ONE ; 如果个位不是0,直接减1 ; 个位是0,十位减1,个位设为9 MOV R5, #9 MOV A, R4 CJNE A, #0, DEC_TEN ; 十位也为0,倒计时结束,切换为暂停状态 MOV R3, #STATE_PAUSE RET DEC_ONE: DEC R5 RET DEC_TEN: DEC R4 RET ; --------------------------- ; 更新显示子程序 ; 控制数码管显示当前十位和个位数值 ; --------------------------- UPDATE_DISPLAY: ; 显示十位 SETB P3.5 MOV A, R4 LCALL DISPLAY MOV P1, A CLR P3.5 LCALL SHORT_DELAY ; 数码管切换延迟 ; 显示个位 MOV A, R5 LCALL DISPLAY MOV P1, A RET ; --------------------------- ; 原有的等待子程序(计时周期) ; --------------------------- WAIT: MOV R0, #0 MOV R2, #8 DELAY_LOOP: DJNZ R0, DELAY_LOOP DJNZ R2, DELAY_LOOP RET ; --------------------------- ; 短延迟子程序(用于按键消抖和数码管切换) ; --------------------------- SHORT_DELAY: MOV R1, #255 SHORT_LOOP: DJNZ R1, SHORT_LOOP RET ; --------------------------- ; 数码管段码查找子程序 ; --------------------------- DISPLAY: INC A MOVC A, @A+PC RET DB 0C0H ;0 DB 0F9H ;1 DB 0A4H ;2 DB 0B0H ;3 DB 99H ;4 DB 92H ;5 DB 82H ;6 DB 0F8H ;7 DB 80H ;8 DB 90H ;9 DB 88H ;A DB 83H ;B DB 0C6H ;C DB 0A1H ;D DB 86H ;E DB 8EH ;F END
关键部分解释
- 状态管理:用R3寄存器存储当前状态,初始为暂停,每次按键按下就切换状态(
CPL R3)。主循环会根据状态决定是等待按键还是执行倒计时。 - 按键消抖:
SHORT_DELAY子程序用来过滤机械按键的抖动,检测到按键按下后,先延迟再确认电平,还要等待按键松开才切换状态,避免一次按下触发多次切换。 - 倒计时逻辑重构:原来的硬编码倒计时被改成了用R4(十位)和R5(个位)存储数值,
DECREMENT_COUNT子程序负责递减数值,到00时自动暂停。 - 显示更新:
UPDATE_DISPLAY子程序负责轮流刷新十位和个位数码管,保证两位数字正常显示。
注意事项
- 请确认你的按键硬件连接:如果按键是高电平有效,需要把
JB P3.2, BUTTON_EXIT改成JNB P3.2, BUTTON_EXIT,相应的等待松开逻辑也要调整。 - 如果计时速度不符合预期,可以调整
WAIT子程序里的R0、R2数值,或者SHORT_DELAY的R1数值来改变延迟时长。
备注:内容来源于stack exchange,提问作者Linfoe
相关产品推荐
相关产品推荐

