8232|32

61

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

在AT89C51上计数器用来定时怎么都准确不了. [复制链接]

在AT89C51上计数器用来定时怎么都准确不了.
在Kiel模拟测试,选定芯片为AT89C51,在频率为12MHz

实验:用计数器每隔10秒把P1.0的位置反一次.

设置计数器0在以16位计数器模式工作,已50毫秒为一次溢出中断.50MS*200=10S
计数器初值计算出为:3CB0

代码如下:
        ORG 0000H
        LJMP MAIN
        ORG 000BH            ;外部中断0入口
        SJMP IF0BREAK
           ORG 0030H            ;程序的开始地址
MAIN:
        SETB EA              ;设置让外部中断0起作用,硬件初始化
        ET0             ;计数器0溢出中断设置
        SETB PT0             ;设置为最高优先级
                       
        MOV TMOD,#01H        ;设置计数器0工作为方式1,16位计数器
        MOV TL0,#0B0H         ;设置计数器0初值,12MHz频率,计数器50ms执行一次就溢出中断
        MOV TH0,#3CH
                       
        MOV R0,#200         ;循环20次为1S,200次为10秒
                       
        SETB TR0            
FINISH:  SJMP $               

;子程序:IF0BREAK
;功能:计数器0溢出中断入口
IF0BREAK:
        CLR ET0                    ;关闭中断响应
        CLR TR0                    ;停止计数器
        DJNZ R0,EXIT               ;满10s就把P1.0位置反,方便查看结果
        JB P1.0,SP1                ;如P1.0=1->SP1
        SETB P1.0
        LJMP STARV                 ;跳转到赋初值的地方
SP1:
         CLR P1.0
STARV:                              ;200次完毕后重赋初值
        MOV R0,#200              
        MOV TL0,#3CH               
        MOV TH0,#0B0H
EXIT:
         SETB TR0               ;启动定时器
         SETB ET0               ;启动中断
RETI                     

END

但是实验结果是1s(可能没到1s)P1.0的信号就会被置反一次.
这是我那里计算出错了吗???

最新回复

考虑中断语句执行时间。在KEILL上仿真,观察语句执行时间。  详情 回复 发表于 2009-12-11 15:57
点赞 关注

回复
举报

66

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
计数器初值计算出为:3CB0
能达到50MS?
不是吧?
你是什么计算的啊?
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
按照公式再算一遍
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

4
 
(2^16 - X)*1 = 50*1000

x = 15536 = 0x3cb0

定时器初值我感觉是对的,可能其他地方错了
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

5
 
每次中断,都要从新赋初值的,而不是200次完了之后再重新赋初值



IF0BREAK:
CLR ET0                    ;关闭中断响应
CLR TR0                    ;停止计数器
MOV TL0,#3CH            
MOV TH0,#0B0H

DJNZ R0,EXIT              ;满10s就把P1.0位置反,方便查看结果
JB P1.0,SP1                ;如P1.0=1->SP1
SETB P1.0
LJMP STARV                ;跳转到赋初值的地方
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

6
 
引用 1 楼 lgy198612 的回复:
计数器初值计算出为:3CB0
能达到50MS?
不是吧?
你是什么计算的啊?
定时初值对着呢,他用的是定时0 模式1 定时50MS
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

7
 
STARV:                              ;200次完毕后重赋初值
MOV R0,#200              
MOV TL0,#3CH              
MOV TH0,#0B0H

这地方的常数高低字节反了......
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

8
 
初值是没错的.

没次中断都重新设置了初值:
代码里面这段
STARV:                       ;200次完毕后重赋初值
        MOV R0,#200              
        MOV TL0,#0BH               
        MOV TH0,#3CH         ;上面代码这里出错了,高低位搞反了.这里改正过来


但是为什么不能定时10s呢????
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

9
 
抱歉了,没搞清楚你的意思,没此中断要赋初值.我在改改代码.
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

10
 
修改代码如下,重新在Kiel里面跑了一遍还是大不到效果啊:
        ORG 0000H
        LJMP MAIN
        ORG 000BH            ;外部中断0入口
        SJMP IF0BREAK
           ORG 0030H            ;程序的开始地址
MAIN:
        SETB EA              ;设置让外部中断0起作用,硬件初始化
        SETB ET0             ;计数器0溢出中断设置
        SETB PT0             ;设置为最高优先级
                       
        MOV TMOD,#01H        ;设置计数器0工作为方式1,16位计数器
        MOV TL0,#0B0H         ;设置计数器0初值,12MHz频率,计数器50ms执行一次就溢出中断
        MOV TH0,#3CH
                       
        MOV R0,#200         ;循环20次为1S,200次为10秒
                       
        SETB TR0             ;启动计数器,要放在所有值后面
FINISH:SJMP $               

;子程序:IF0BREAK
;功能:计数器0溢出中断入口
IF0BREAK:
        CLR ET0                    ;关闭中断响应
        CLR TR0                    ;停止计数器
        MOV TL0,#0B0H              ;每次中断都要赋初值,而不是等待200次完毕在赋值
        MOV TH0,#3CH
       
        DJNZ R0,EXIT               ;满10s就把P1.0位置反,方便查看结果
        JB P1.0,SP1                ;如P1.0=1->SP1
        SETB P1.0
        LJMP STARV                 ;跳转到赋初值的地方
SP1:
        CLR P1.0
STARV:                       ;200次完毕后重赋初值
        MOV R0,#200              
EXIT:
        SETB TR0               ;启动定时器
         SETB ET0               ;启动中断
RETI                     ;返回到主程序

END

怎么搞.
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

11
 
首先要计数准确的话不要用12M,要用11.0592M。用12M还不如用C写得了
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

12
 
在另一个贴里给你放了个代码,不知道可行不
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

13
 

 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

14
 
引用 10 楼 lgy198612 的回复:
首先要计数准确的话不要用12M,要用11.0592M。用12M还不如用C写得了


12分频后刚刚好是一M对于时间来说,这个比11.XXX那个准得多吧?

 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

15
 
;子程序:IF0BREAK
;功能:计数器0溢出中断入口
IF0BREAK:
CLR ET0                    ;关闭中断响应
CLR TR0                    ;停止计数器
DJNZ R0,EXIT              ;满10s就把P1.0位置反,方便查看结果
JB P1.0,SP1                ;如P1.0=1->SP1
SETB P1.0
LJMP STARV                ;跳转到赋初值的地方
SP1:
        CLR P1.0
STARV:                              ;200次完毕后重赋初值
MOV R0,#200
EXIT:            
MOV TL0,#3CH              
MOV TH0,#0B0H

        SETB TR0              ;启动定时器
        SETB ET0              ;启动中断
RETI                     

END

我觉得你这样做好一点,你试试看。原因是你的定时器第一次执行完50ms时你没有再次赋初值,而是从上次停止的计数开始
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

16
 
引用 6 楼 great_bug 的回复:
STARV:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ;200次完毕后重赋初值
MOV R0,#200
MOV TL0,#3CH
MOV TH0,#0B0H

这地方的常数高低字节反了......

确实反了啊  应该是
MOV TH0,#3CH
MOV TL0,#0B0H
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

17
 
将T0设置成自动重装载模式,初值=6,用的12M晶振,那么0.25ms中断一次,在T0的中断程序里计数,达到40000次将P1.0翻转即可,这样会省去每次中断赋初值的时间,从而定时更准确,LZ试试看吧
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

18
 
我在多试过几次结果一样的,原理10S的东西,他1S就跑完了.
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

19
 
你不会是看着钟看KEIL仿真吧? 不要看实际时间,要看仿真给出的时间.....因为你的PC实在是太快了,KEIL仿真要比实际目标快的多..................
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

20
 
怎么看仿真时间啊.
我就是对着电脑时钟来看的啊.我说怎么都没10S呢.
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表