找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1037|回复: 21
收起左侧

采用单片机定时器0的工作方式1写一段5ms的延时函数,请大家帮我看看哪里出了问题?

[复制链接]
ID:645485 发表于 2023-5-18 01:20 | 显示全部楼层 |阅读模式
一:问题描述
按照文中单片机代码编译下载后,P1口LED不闪烁,一直亮。然后通过Keil uVision5软件仿真,延时时间也不是期望的0.5s。请大家帮我看看是怎么回事?

二:硬件环境
STC12C2052AD  //12MHz  //P1口外接LED
采用定时器0的工作方式1写一段延时5ms的函数,然后调用延时函数,使P1口外接的LED每0.5s闪烁一次。

三:软件环境
Keil uVision5

四:示例代码如下(采用查询方法)
  1. #include <STC12C2052AD.H>

  2. //以下是采用定时器0的 5ms延时函数
  3. void delay(unsigned int i)      //延时程序,i是形式参数
  4. {
  5.         TMOD = 0X01;                 //设定定时器0为工作方式1
  6.         IE    = 0X00;                 //禁止中断
  7.         TR0 = 1;                    //启动定时器0
  8.         while(i != 0)               //执行i次循环
  9.         {
  10.                 TH0 = 0XEC;
  11.                 TL0 = 0X78;               //设定计数脉冲为XX次
  12.                 while(TF0 != 1);         //计时时间不到,等待;计时时间到,计数溢出位置1,即TF0=1
  13.                 i--;                      //循环次数减1
  14.         }
  15.         TR0 = 0;                   //关闭定时器0
  16. }

  17. //以下是主程序
  18. void main()
  19. {
  20.         for(;;)
  21.         {
  22.                 P1 = 0X00;          //P1口LED全亮
  23.                 delay(100);         //延时100*5ms=0.5s
  24.                 P1 = 0XFF;         //P1口LED全灭
  25.                 delay(100);         //延时100*5ms=0.5s
  26.         }
  27. }
复制代码

五:定时器0的工作方式1初值计算如下:
工作方式1的定时时间.png

六:Keil设置如下:
Keil设置.png

七:软件仿真如下:
软件仿真.png

八:自己挖的坑自己填!
仔细对照书中代码,发现少了一句,如下:
少了一句,将计数溢出位清零.png

九:程序重新编译下载后,虽然LED闪烁了,但是软件仿真结果还不是期望的0.5s,不知道怎么回事?希望大家帮我看看!多谢了!
不是期望的0.5s.png
回复

使用道具 举报

ID:301191 发表于 2023-5-18 17:37 | 显示全部楼层
顶一下
回复

使用道具 举报

ID:645485 发表于 2023-5-18 18:41 | 显示全部楼层
顶啥呢,有时间帮我看看喽,分析一下,我是真没辙了。先感谢一下!
回复

使用道具 举报

ID:213173 发表于 2023-5-18 20:54 | 显示全部楼层
tongguan123 发表于 2023-5-18 18:41
顶啥呢,有时间帮我看看喽,分析一下,我是真没辙了。先感谢一下!

楼主这个定时器用法是哪个老师教的?
  1. #include <STC12C2052AD.H>

  2. void Timer0Init(void)                //5毫秒@12.000MHz
  3. {
  4.         AUXR &= 0x7F;                //定时器时钟12T模式
  5.         TMOD &= 0xF0;                //设置定时器模式
  6.         TMOD |= 0x01;                //设置定时器模式
  7.         TL0 = 0x78;                //设置定时初始值
  8.         TH0 = 0xEC;                //设置定时初始值
  9.         TF0 = 0;                //清除TF0标志
  10.         TR0 = 1;                //定时器0开始计时
  11. }


  12. //以下是主程序
  13. void main()
  14. {
  15.         unsigned char num;
  16.         Timer0Init();
  17.         while(1)
  18.         {
  19.                 if(TF0)
  20.                 {
  21.                         TF0=0;
  22.                         TL0 = 0x78;                //设置定时初始值
  23.                         TH0 = 0xEC;                //设置定时初始值
  24.                         num++;
  25.                         if(num==100)
  26.                         {
  27.                                 num=0;
  28.                                 P1=~P1;//P1口取反
  29.                         }
  30.                 }       
  31.         }
  32. }
复制代码
回复

使用道具 举报

ID:1073939 发表于 2023-5-19 09:14 | 显示全部楼层
软件仿真使用stc芯片有问题,要改用通用芯片。

评分

参与人数 1黑币 +70 收起 理由
admin + 70 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:123289 发表于 2023-5-19 09:28 | 显示全部楼层
1、定时器的时钟源是晶振,所以需以根据晶振的频率不计算时间常数。
2、while(TF0 != 1);         是等待计数溢出位TF=1,是可以等到的,但它不会自动清0,也即从此后一直为1。因为以后的while(TF0 != 1)会被路过。
3、是外话。这种程序方式延时,严重占用CPU资源,与DELAY并无二样,失去了定时器的设计初衷。
4、较好的做法是,将时常数计算并设计到5ms,起动中断。如此每5ms产生一次中断,在中断服务中做个标记B5MS。主程序凭B5MS标记处理事件,完成后清除B5MS标记。如果处理的事件用时不长,如仅开关一个灯。可以不用B5MS标记,而直接在中断服务程序中处理。
回复

使用道具 举报

ID:161164 发表于 2023-5-19 10:09 | 显示全部楼层
可能是Keil对STC12的速度有点误会
设定500ms,仿真125ms,快了4倍
把12M改为3Mhz就行了
回复

使用道具 举报

ID:645485 发表于 2023-5-19 11:40 | 显示全部楼层
wulin 发表于 2023-5-18 20:54
楼主这个定时器用法是哪个老师教的?
你好,大侠:        首先非常感谢你花时间回答我的问题,再次表示衷心的感谢!通过对你提供的代码进行编译下载后,P1口的LED灯也确实闪烁了,但我对你的代码在Keil软件中仿真,发现时间好像还不是期望的0.5s,也不知是我仿真方法的问题,还是怎么回事?图片如下:
1.png     2.png 4.png

       其次呢,关于示例代码我也是参考别的资料的,原本它使用的是AT的单片机,里面没有这个关于辅助寄存器AUXR的配置,但我确实使用的是STC12C2052AD,我的示例代码中,没有对其进行配置,那默认值就是0,即复位后定时器0和定时器1就是传统8051,即12分频。所以没有配置这个寄存器,好像也没关系,但最好还是进行配置,你说对吧?
3.png

      然后你能不能对你的代码仿真试一下,或编译下载试试,看看到底是不是期望的0.5s。我这里没有合适的测量工具,只能寄希望于你了。当然是在你有时间并且愿意的情况下。
      最后,还是要感谢你无私的分享与帮助,无以言表,只能祝你工作顺利、开开心心!

回复

使用道具 举报

ID:645485 发表于 2023-5-19 11:42 | 显示全部楼层
ydatou 发表于 2023-5-19 09:14
软件仿真使用stc芯片有问题,要改用通用芯片。
Really?这个我还真不知道!
回复

使用道具 举报

ID:645485 发表于 2023-5-19 11:45 | 显示全部楼层
lkc8210 发表于 2023-5-19 10:09
可能是Keil对STC12的速度有点误会
设定500ms,仿真125ms,快了4倍
把12M改为3Mhz就行了
这是什么道理?以前有遇到过同类问题吗???
回复

使用道具 举报

ID:645485 发表于 2023-5-19 11:48 | 显示全部楼层
ydatou 发表于 2023-5-19 09:14
软件仿真使用stc芯片有问题,要改用通用芯片。

你以前处理过类似的问题吗?
回复

使用道具 举报

ID:645485 发表于 2023-5-19 12:03 | 显示全部楼层
yzwzfyz 发表于 2023-5-19 09:28
1、定时器的时钟源是晶振,所以需以根据晶振的频率不计算时间常数。
2、while(TF0 != 1);         是等待 ...
首先感谢分享与帮助!我是最近学习学到定时器这里,想充分理解它,查询功能和中断功能都要学习。实际使用中,当然会用定时器的中断功能,这里使用的查询功能,产生延时的效果,只是理解寄存器的相关配置。
1:定时功能的计数脉冲选择的是内部时钟(或分频、或不分频)得到;
     计数功能的计数脉冲当然是外部脉冲信号了。
2:定时器0的计数溢出标志位TF0在计数溢出后,如果要产生延时,需要软件清零,然后再定义个循环变量,达到延时效果。
回复

使用道具 举报

ID:94253 发表于 2023-5-19 12:11 | 显示全部楼层
STC12C2052AD应该是1T单片机吧,计数初值搞错了
回复

使用道具 举报

ID:213173 发表于 2023-5-19 12:13 | 显示全部楼层
tongguan123 发表于 2023-5-19 11:40
你好,大侠:        首先非常感谢你花时间回答我的问题,再次表示衷心的感谢!通过对你提供的代码进行编 ...

这个程序在实物上运行没有任何问题,AUXR &= 0x7F;也可以省略,其默认就是12T。Keil软件仿真STC1T单片机结果不一定符合实际。
回复

使用道具 举报

ID:77589 发表于 2023-5-19 14:11 | 显示全部楼层
好久没用51了,围观一下
回复

使用道具 举报

ID:645485 发表于 2023-5-19 14:13 | 显示全部楼层
lym_tb_1 发表于 2023-5-19 12:11
STC12C2052AD应该是1T单片机吧,计数初值搞错了
5.png
回复

使用道具 举报

ID:645485 发表于 2023-5-19 14:15 | 显示全部楼层
wulin 发表于 2023-5-19 12:13
这个程序在实物上运行没有任何问题,AUXR &= 0x7F;也可以省略,其默认就是12T。Keil软件仿真STC1T单片机 ...
再次感谢指导!
回复

使用道具 举报

ID:645485 发表于 2023-5-19 14:59 | 显示全部楼层
tongguan123 发表于 2023-5-19 11:42
Really?这个我还真不知道!
确实如你所说,我将设备改成传统8051,不管是用我的代码,还是上面一位大侠提供的代码,在Keil里面软件仿真,都是我所期望的0.5S。我的代码仿真如下: 1.png 2.png


大侠的代码仿真如下:

1.png



回复

使用道具 举报

ID:645485 发表于 2023-5-19 15:08 | 显示全部楼层
wulin 发表于 2023-5-18 20:54
楼主这个定时器用法是哪个老师教的?
你好,我听从上面一位热心朋友的建议,将STC改成传统8051单片机,然后使用你的代码软件仿真,得到了期望的0.5s.效果如下:
11.png 2.png


回复

使用道具 举报

ID:645485 发表于 2023-5-19 15:10 | 显示全部楼层
tongguan123 发表于 2023-5-19 11:42
Really?这个我还真不知道!
再次感谢分享!
回复

使用道具 举报

ID:645485 发表于 2023-5-19 15:24 | 显示全部楼层
ydatou 发表于 2023-5-19 09:14
软件仿真使用stc芯片有问题,要改用通用芯片。

不好意思,我刚才自己给自己回复了,没传达给你我的谢意,again。首先感谢你的分享与建议!按照你的方法,得到了期望的延时效果(0.5s),
使用我的代码进行软件仿真,效果如下:
1.png 2.png


使用上面一位大侠代码进行软件仿真,效果如下:
11.png 2.png



回复

使用道具 举报

ID:645485 发表于 2023-5-19 16:01 | 显示全部楼层
ydatou 发表于 2023-5-19 09:14
软件仿真使用stc芯片有问题,要改用通用芯片。
感谢你的话不知被我回复到哪里去了?我晕根据你的方法,问题解决了。再次感谢!
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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