You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:35:34