打印

读取TH0,TL0的值的问题

[复制链接]
14630|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
风溪香士|  楼主 | 2012-8-29 17:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我写的一个程序,需要读取TH0,TL0的值,用time=256*TH0+TL0;可正确读取,而用time|=TH0;   time<<=8;   time|=TL0;却不能。具体情况如下。
外部中断0和定时器0初始化:
P3=0;
TMOD=0x09;
TH0=0;
TL0=0;
IT0=1;
EA=1;
EX0=1;
TR0=1;
外部中断0服务函数:
void int0() interrupt 0
{
// time|=TH0;
// time<<=8;
// time|=TL0;
time=256*TH0+TL0;
// time_l=TL0;
// time_h=TH0;
// time|=time_h;
// time<<=8;
// time|=time_l;
TH0=0;
TL0=0;
}
我是测试HC-SR04超声波模块,它的输出脚接在P32,会输出一个脉冲,我就是要计算这脉冲的高电平时间。
设定了定时器0的GATE位为1,当P32的高电平开始时,TH0,TL0开始计数,当高电平结束时,产生负跳变,进入中断服务函数,计算时间。
以上就是程序的思路。
问题在于,如果用time=256*TH0+TL0;计算时间,得到的值符合实际,time的值为几百;而如果用此语句的上面三句,或者下面四句(见上面中断服务函数)来计算时间,得到的值不符合实际,time的值为几万。
请各位前辈指点一下,为何会这样?

相关帖子

沙发
zuanze| | 2012-8-30 09:53 | 只看该作者
我觉得使用time=256*TH0+TL0;一次提取TH0,TL0的值

而使用其他的方式,当提取TL0的时候,值已经发生很大的变化,
因为你的定时器是一直开着的,而且一直在计数,值一直在变化,
而且计数的周期应该比你语句执行的时间短的多.......

使用特权

评论回复
板凳
zhuanghaiyang| | 2012-8-30 10:18 | 只看该作者
不解。我也想知道

使用特权

评论回复
地板
李冬发| | 2012-8-30 12:00 | 只看该作者
time=256*TH0+TL0;
-------------
LZ,你不关定时器就用这个式子,风险太高了吧。

使用特权

评论回复
5
coody| | 2012-8-30 12:48 | 只看该作者
LZ,你用后者操作,要先清除。
另外,读时要考虑刚好有进位。我一般读两次TH0,示意程序:
a = TH0;
b = TL0;
if(a != TH0)  a = TH0;

使用特权

评论回复
6
yimankehao| | 2012-8-30 12:49 | 只看该作者
LZ程序里面测到HC-SR04超声波模块输出脉冲脉冲后应该把定时器关掉,这个时候再去计算time就对了。

使用特权

评论回复
7
风溪香士|  楼主 | 2012-8-30 19:35 | 只看该作者
4# 李冬发
我设置了TMOD里的GATE位为1,进入中断时外部中断0已经为低,TH0,TL0不会再计数了。而且我试过在中断函数头开计时,函数尾关计时,效果一样。

使用特权

评论回复
8
风溪香士|  楼主 | 2012-8-30 19:35 | 只看该作者
2# zuanze
我设置了TMOD里的GATE位为1,进入中断时外部中断0已经为低,TH0,TL0不会再计数了。而且我试过在中断函数头开计时,函数尾关计时,效果一样。

使用特权

评论回复
9
风溪香士|  楼主 | 2012-8-30 19:39 | 只看该作者
5# coody
要清除什么?

使用特权

评论回复
10
风溪香士|  楼主 | 2012-8-30 19:41 | 只看该作者
6# yimankehao
你是说刚开始有高电平时就关定时器?

使用特权

评论回复
11
yimankehao| | 2012-8-30 20:05 | 只看该作者
10# 风溪香士
HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。
基本工作原理:
(1)采用IO TRIG 触发测距,给最少10us 的高电平信呈。
(2)模块自动发送8 40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;
当你检测到ECHO有一个高电平开定时器,检测到ECHO为低再关定时器。这样时间就准了

使用特权

评论回复
12
lzqxs89| | 2012-8-31 11:29 | 只看该作者
学习啦。

使用特权

评论回复
13
风溪香士|  楼主 | 2012-8-31 11:38 | 只看该作者
11# yimankehao
我程序的思路就是这样的,设置定时器0的TMOD的GATE位为1,当外部中断0为高时(ECHO接外部中断0),TH0,TL0才计时,当外部中断0高电平结束,产生负跳变,进入中断服务函数,读出TH0,TL0,计算时间time。
现在的问题是,两种计算时间的方式得到的结果不一样。为什么用time|=TH0;      time<<=8;     time|=TL0;不能得到正确的时间?

使用特权

评论回复
14
vrgood| | 2012-8-31 15:29 | 只看该作者
老天爷在罚你学业不精。
time|=TH0;      time
kimfufree 发表于 2012-8-31 12:30

应该是这个道理

使用特权

评论回复
15
雷影少年| | 2012-8-31 16:00 | 只看该作者
14# kimfufree
是这样,我也遇到过类似的问题,在time|=TH0; time<<=8; time|=TL0;前加个time=0;试试

使用特权

评论回复
16
zhuanghaiyang| | 2012-8-31 17:27 | 只看该作者
取值之前先关中断将time清0,然后再取就没问题了

使用特权

评论回复
17
sedatefire| | 2012-9-1 00:31 | 只看该作者
一句话,你这个time必定是全局变量
使用前清零即可

使用特权

评论回复
18
sedatefire| | 2012-9-1 00:32 | 只看该作者
当然,time=TH0的写法,效率会高一些

使用特权

评论回复
19
sedatefire| | 2012-9-1 00:37 | 只看该作者
你这样写得到的时间值,依旧有几个clock的误差
误差=中断响应时间+压栈时间+乘法或者移位指令操作时间

不过因为每次都是这样的误差,相对误差反而没有了
但绝对误差还是存在的
要不要扣除这些误差,看你系统要求的精度了

使用特权

评论回复
20
风溪香士|  楼主 | 2013-4-29 16:20 | 只看该作者
kimfufree 发表于 2012-8-31 12:30
老天爷在罚你学业不精。
time|=TH0;      time

明白了,确实是学业不精啊:(

使用特权

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

本版积分规则

个人签名:我命由我不由天!

13

主题

82

帖子

1

粉丝