打印

89F52用定时器0定时,发现时间有些不对

[复制链接]
1912|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mcuatmel|  楼主 | 2010-11-9 10:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用16bit模式定时5ms,12MHz外部晶振,程序如下:
TMOD = 0x11;
TCON|= 0x01; //外中断0,边沿触发
TH0  = 0xec;        //12MHz,5ms
TL0  = 0x78;
TR0=1;


void Timer0_ISR() interrupt 1
{
TH0=0xEC;
TL0=0x78;
g_second++;
if(g_second>199)
{
  g_second=0;
  g_count++;
  g_LineLong++;
}

发现1分钟估计能差13秒上下,请高手指点。
沙发
bananarer| | 2010-11-9 12:06 | 只看该作者
不好意思,我算不出来你
TH0  = 0xec;        //12MHz,5ms
TL0  = 0x78;

是不是systemclock分频过了啊?
假如你12分频了。由于Timer0 16bit模式不是自动重载的,所以会有误差的。但是1分钟13秒太多了点,难道还有其他的原因还是说1小时有13秒误差?  :)

使用特权

评论回复
板凳
mcuatmel|  楼主 | 2010-11-9 14:52 | 只看该作者
没分频
65536-5000=60536 <--->0xEC78  
12M下1uS刚好是一个定时计数
不是自动重装,所以
void Timer0_ISR() interrupt 1
{
TH0=0xEC;//先恢复计数初值
TL0=0x78;
...
}

使用特权

评论回复
地板
mcuatmel|  楼主 | 2010-11-9 14:53 | 只看该作者
这种算法时间只会长不会短。不知道为什么会1分钟少了那么长时间。

使用特权

评论回复
5
刘前辈| | 2010-11-11 15:24 | 只看该作者
本帖最后由 刘前辈 于 2010-11-12 09:51 编辑

改写T0中断程序:

void Timer0_ISR() interrupt 1
{
TL0 |= 0x78;     // 或者就 TL=0x78;   前后位置反一下,大不一样。

TH0=0xEC;
g_second++;
if(g_second>199)
……


最好10ms -0xD8F0 容易成功,保证16us之内必然响应中断。0xec78要求T0必须在8us内响应。理论上也可以。

这种算法时间只会长不会短。不知道为什么会1分钟少了那么长时间。


LZ的算法只能使软时钟比实际时间慢,而不会快。

使用特权

评论回复
6
mcuatmel|  楼主 | 2010-11-19 09:35 | 只看该作者
这种算法在其它的51上都好用,用了好多年了,不知在这儿为什么不好用。我还不知道通讯会不会有问题,少量数据还没发出问题不多了会不会有问题。
今天又发现定时器0,用外中断0采样方波,用定时器0做波形周期计时,发现也差了大约1/4-1/5的样子,都不知道该咋办了。

使用特权

评论回复
7
bananarer| | 2010-11-19 12:52 | 只看该作者
没分频
65536-5000=60536 0xEC78  
12M下1uS刚好是一个定时计数
不是自动重装,所以
void Timer0_ISR() interrupt 1
{
TH0=0xEC;//先恢复计数初值
TL0=0x78;
...
}

12M下面1us有12个定时计数,88F52是1T的单片机,不是12T的。所以程序不可以和其他51一致的。


mcuatmel 发表于 2010-11-9 14:52

使用特权

评论回复
8
mcuatmel|  楼主 | 2010-11-19 13:25 | 只看该作者
定时器默认的情况下不是12T的吗?

使用特权

评论回复
9
Jack602| | 2010-11-20 20:55 | 只看该作者
这程序绝对没错,51都用过好几次了,建议LZ换块单片机试试

使用特权

评论回复
10
mcuatmel|  楼主 | 2010-11-21 09:48 | 只看该作者
问题找到了,忘记修改时钟源,在下载工具中把单片机的时钟改成外部晶振<=16M那项就行了,这回时间基本差不多。用习惯了常用51单片机,没想起来要从外部改时钟。

使用特权

评论回复
11
yixindianzi| | 2010-11-21 11:49 | 只看该作者
路过,留个脚印。

使用特权

评论回复
12
宋倩2010| | 2010-11-21 20:03 | 只看该作者
呵呵,慢慢来就知道了

使用特权

评论回复
13
sszxxm| | 2010-11-23 08:31 | 只看该作者
定时累计要想精确,我的做法是尽量配置TH,TL的TL初值为0,这样每次中断进去无需给TL重新赋初值,反正定时器没有停,中断进去即使延迟一点,TL0还是照样走,进中断只要给TH赋值一次,就可以了,而且在TL0在中断之后溢出进位到TH之前,只要保证在256个时钟周期之内给TH赋值,那么整个定时累计精度就只和你的晶振时钟精度有关了。

有很多办法可以使TL初值为0,调整定时长度,修改分频比,选择合适的晶振等等。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

512

主题

1455

帖子

2

粉丝