8051汇编双路方波输出异常求助(Proteus仿真)
8051双定时器波形生成问题排查与修复
需求说明
通过8051的P2.6、P2.7端口生成两路方波,配合P2.0开关实现两种工作模式:
- MODE0(P2.0低电平):P2.6输出460Hz、50%占空比;P2.7输出230Hz、50%占空比
- MODE1(P2.0高电平):交换两路频率,且占空比降至25%
当前问题:单独使用单个定时器时功能正常,同时启用两个定时器后,MODE0下输出波形周期严重偏离预期(从微秒级变为数百毫秒级),尽管TH/TL值计算正确。
问题根源分析
原代码存在两个核心问题:
- 定时器重复初始化:每次进入MODE0时会重复执行
SETB TR0、SETB TR1并重新加载TL/TH值,导致定时器计数被频繁重置,无法正常溢出 - 未重装载定时器初值:定时器模式1(16位)溢出后不会自动重装载初值,原代码仅清除TF标志位但未重新写入TL/TH,第一次溢出后定时器从0开始计数,周期完全错误
修正后的汇编代码
ORG 0000H SETUP: MOV TMOD, #11H ; 定时器0、1均设为模式1(16位定时器) MOV P2, #0FFH ; P2口初始化,拉高所有引脚(开关引脚默认高电平,输出引脚默认高) MAIN: MOV C, P2.0 ; 读取P2.0开关状态 JC MODE1 ; 高电平跳转至MODE1 SJMP MODE0 ; 低电平进入MODE0 ; -------------------------- MODE0 低电平模式 -------------------------- MODE0: ; 先停止定时器,避免切换时计数混乱 CLR TR0 CLR TR1 ; 定时器0:460Hz方波,50%占空比 → 半周期1086.9μs(晶振11.0592MHz,机器周期1.085μs) MOV TL0, #0FAH MOV TH0, #0F7H ; 定时器1:230Hz方波,50%占空比 → 半周期2173.9μs MOV TL1, #17H MOV TH1, #0FCH ; 启动定时器 SETB TR0 SETB TR1 LOOPM0: MOV C, P2.0 JC MODE1 ; 开关跳变则切换模式 JB TF0, RELOAD0 ; 定时器0溢出则重装载并翻转引脚 JB TF1, RELOAD1 ; 定时器1溢出则重装载并翻转引脚 SJMP LOOPM0 RELOAD0: CPL P2.6 ; 翻转P2.6输出 MOV TL0, #0FAH ; 重装载定时器0初值 MOV TH0, #0F7H CLR TF0 ; 清除溢出标志 SJMP LOOPM0 RELOAD1: CPL P2.7 ; 翻转P2.7输出 MOV TL1, #17H ; 重装载定时器1初值 MOV TH1, #0FCH CLR TF1 ; 清除溢出标志 SJMP LOOPM0 ; -------------------------- MODE1 高电平模式 -------------------------- MODE1: ; 停止定时器,切换前重置 CLR TR0 CLR TR1 ; 交换频率+25%占空比:P2.6输出230Hz,P2.7输出460Hz;高低电平时间比1:3 ; 定时器0:对应1086.9μs(每2次溢出翻转P2.6,实现25%占空比) MOV TL0, #0FAH MOV TH0, #0F7H ; 定时器1:对应543.4μs(每2次溢出翻转P2.7,实现25%占空比) MOV TL1, #0BH MOV TH1, #0FDH ; 初始化翻转计数寄存器 MOV R0, #00H ; R0计数定时器0溢出次数 MOV R1, #00H ; R1计数定时器1溢出次数 ; 启动定时器 SETB TR0 SETB TR1 LOOPM1: MOV C, P2.0 JNC MODE0 ; 开关跳变则切换回MODE0 JB TF0, COUNT0 JB TF1, COUNT1 SJMP LOOPM1 COUNT0: INC R0 MOV TL0, #0FAH ; 重装载定时器0初值 MOV TH0, #0F7H CLR TF0 CJNE R0, #02H, LOOPM1 ; 计数到2次才翻转引脚 CPL P2.6 MOV R0, #00H ; 重置计数 SJMP LOOPM1 COUNT1: INC R1 MOV TL1, #0BH ; 重装载定时器1初值 MOV TH1, #0FDH CLR TF1 CJNE R1, #02H, LOOPM1 ; 计数到2次才翻转引脚 CPL P2.7 MOV R1, #00H ; 重置计数 SJMP LOOPM1 END
关键修复点说明
- 模式切换时重置定时器:进入任何模式前先关闭定时器,重新加载初值后再启动,避免模式切换时计数混乱
- 定时器溢出后重装载初值:每次定时器溢出后,必须重新写入TL/TH值,保证定时器按固定周期溢出
- MODE1的25%占空比实现:通过寄存器计数定时器溢出次数,每2次溢出才翻转一次引脚,实现1:3的高低电平时间比
- P2口初始化:拉高P2口所有引脚,避免初始状态不确定导致的异常输出
内容的提问来源于stack exchange,提问作者DevKara
相关产品推荐
相关产品推荐

