找回密码
 立即注册
查看: 125|回复: 7

帮我看看代码,定时器怎么失效了

[复制链接]
已绑定手机

82

主题

218

回帖

700

积分

高级会员

积分
700
发表于 2026-8-16 11:16:45 | 显示全部楼层 |阅读模式
我的是擎天柱,现在给P2赋为0,现在灯一直亮,但是不闪,刚才还好好的呢

  1. #include <AI8051U.H>                         //包含AI8051U的头文件
  2. #include <intrins.H>
  3. #include  "ai_usb.h"        //USB库和USB虚拟设备的头文件
  4. void Timer0_Init(void)                //100毫秒@40.000MHz
  5. {
  6.         TM0PS = 0x3F;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
  7.         AUXR |= 0x80;                        //定时器时钟1T模式
  8.         TMOD &= 0xF0;                        //设置定时器模式
  9.         TL0 = 0xDC;                                //设置定时初始值
  10.         TH0 = 0x0B;                                //设置定时初始值
  11.         TF0 = 0;                                //清除TF0标志
  12.         TR0 = 1;                                //定时器0开始计时
  13. }
  14. void main(void)
  15. {
  16.     EAXFR = 1;                      //允许访问扩展的特殊寄存器,XFR
  17.                                     //(32 位模式请使用这句,注释下一句)
  18. //  P_SW2 |= 0x80;                  //允许访问扩展的特殊寄存器,XFR
  19.                                     //(8位模式请使用这句,注释上一句)。
  20.     WTST = 0;                       //设置取程序代码等待时间,
  21.                                     //赋值为 0表示不等待,程序以最快速度运行
  22.     CKCON = 0;                      //设置访问片内的 xdata速度,
  23.                                     //赋值为 0表示用最快速度访问,不增加额外的等待时间
  24.                                     
  25.     P2M0 = 0x00; P2M1 = 0x00;       //设置P2口为准双向口模式
  26.     P3M0 = 0x00; P3M1 = 0x00;       //设置P3口为准双向口模式
  27.                
  28.                 P2=0;
  29.        
  30.                 usb_init();
  31.         //初始化USB模块,并且会将【P3.0,P3.1】初始化为高阻输入,不影响USB【D-,D+】通讯
  32.           Timer0_Init();
  33.           EA = 1;                //使能总中断
  34.        
  35.     while(1)                        
  36.     {            
  37.     }
  38. }
  39. void Timer0_Isr(void) interrupt 1
  40. {
  41.        
  42.                            //LED循环自动闪烁部分
  43.         P2 = ~P2;                   //对P0端口取反
  44. //      P00 = ~P00;                //对单个端口取反
  45.        
  46. }
复制代码


回复

使用道具 举报 送花

已绑定手机

74

主题

1003

回帖

3653

积分

论坛元老

初出茅庐&无甚本事

积分
3653
发表于 2026-8-16 11:38:03 | 显示全部楼层
可能缺少ET0 = 1;

以前用的这个

void Timer0_Isr(void) interrupt 1
{
}

void Timer0_Init(void)                //100us@11.0592MHz
{
        AUXR |= 0x80;                        //imer clock is 1T mode
        TMOD &= 0xF0;                        //Set timer work mode
        TL0 = 0xAE;                                //Initial timer value
        TH0 = 0xFB;                                //Initial timer value
        TF0 = 0;                                //Clear TF0 flag
        TR0 = 1;                                //Timer0 start run
        ET0 = 1;                                //Enable timer0 interrupt
}
偶尔看看玩玩
回复

使用道具 举报 送花

865

主题

1万

回帖

2万

积分

管理员

积分
25122
发表于 2026-8-16 12:07:20 | 显示全部楼层
截图202608161207162782.jpg
回复

使用道具 举报 送花

865

主题

1万

回帖

2万

积分

管理员

积分
25122
发表于 2026-8-16 12:07:38 | 显示全部楼层

手册确认了关键信息。现在我可以给出准确的分析。

问题分析

您帖子里遇到的"定时器失效、灯一直亮但不闪"的问题,根源在于缺少了 ET0 = 1; 这一句。

为什么灯不闪?

您的主程序里虽然执行了:

Timer0_Init();   // 定时器0初始化
EA = 1;          // 使能总中断

但根据 AI8051U 数据手册《中断系统》 一章的中断使能寄存器(IE)说明,中断允许是多级控制的:

"EA:总中断允许控制位。**EA的作用是使中断允许形成多级控制。**即各中断源首先受EA控制;其次还受各中断源自己的中断允许控制位控制。"

也就是说,中断要能进入,必须同时满足两个条件:

  1. 总中断 EA = 1(您已经做了)
  2. 对应中断源自身的使能位要让能(您漏掉了)

对于定时器0,就是 ET0(定时/计数器 T0 的溢出中断允许位)

"ET0:定时/计数器T0的溢出中断允许位。
0:禁止T0中断
1:允许T0中断"

您的 Timer0_Init() 里只启动了定时器(TR0 = 1),但没有把 ET0 置 1,所以定时器虽然在跑,但它的中断请求无法被 CPU 响应,中断服务函数 Timer0_Isr 永远不会被执行,P2 = ~P2 自然也就不会执行 —— 灯就一直亮着不闪了。

您之前"还好好的",为什么突然失效?

很可能您之前用的例程(或早期版本)里是有 ET0 = 1; 的,后来改写代码时不小心把这句删掉了。这也是论坛回复中"狂热***"提醒你"可能缺少 ET0 = 1"的原因,他给出的正确初始化里就明确包含了 ET0 = 1; //Enable timer0 interrupt

正确的修改方法

请在您的 Timer0_Init() 函数中、TR0 = 1; 之后(或之前)补上 ET0 = 1;

void Timer0_Init(void)                //100毫秒@40.000MHz
{
    TM0PS = 0x3F;                     //设置定时器时钟预分频
    AUXR |= 0x80;                     //定时器时钟1T模式
    TMOD &= 0xF0;                     //设置定时器模式
    TL0 = 0xDC;                       //设置定时初始值
    TH0 = 0x0B;                       //设置定时初始值
    TF0 = 0;                          //清除TF0标志
    TR0 = 1;                          //定时器0开始计时
    ET0 = 1;                          //★ 使能定时器0中断(缺失这句导致不闪)
}

修改后,配合主程序里的 EA = 1;,定时器0的中断就能正常响应,LED 就会开始闪烁了。

小结

中断响应条件 您代码中状态
EA = 1(总中断) ✅ 已有
ET0 = 1(T0中断允许) 缺失,需补上
TR0 = 1(定时器运行) ✅ 已有

信息来源:AI8051U 数据手册《中断系统》章节——中断使能寄存器(IE)中 ET0 及 EA 的多级控制说明。

方便的话,您可以补上这句后再测一下,如果还有问题欢迎继续反馈。另外如果您的实验板接有 USB 相关中断,也请确认不影响定时器中断的响应优先级。


🔍 搜索 "https://www.stcaimcu.com/thread-25299-1-1.html"

⏱️ 查找用时 8.3s | 总回答用时 16.0s

回复

使用道具 举报 送花

83

主题

8219

回帖

1万

积分

超级版主

积分
17644
发表于 2026-8-16 14:12:36 | 显示全部楼层
没有允许定时器0中断:
ET0 = 1;
回复

使用道具 举报 送花

已绑定手机

10

主题

409

回帖

1119

积分

金牌会员

积分
1119
发表于 2026-8-16 15:13:10 | 显示全部楼层
无标题.jpg
回复

使用道具 举报 送花

已绑定手机

82

主题

218

回帖

700

积分

高级会员

积分
700
 楼主| 发表于 2026-8-17 09:37:59 | 显示全部楼层

感谢,已经解决了
回复

使用道具 举报 送花

已绑定手机

82

主题

218

回帖

700

积分

高级会员

积分
700
 楼主| 发表于 2026-8-17 09:38:34 | 显示全部楼层
狂热*** 发表于 2026-8-16 11:38
可能缺少ET0 = 1;

以前用的这个

感谢,已经解决了
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-9-23 16:09 , Processed in 0.073105 second(s), 78 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表