最近在用Proteus8.9仿真51单片机的一些实验程序时出现了一个问题:仿真DS18B20不成功,现象如下:
晶体管显示的数值固定不变,我把这个程序放到开发板上去跑,就没有半点问题。后来了解到,由于DS18B20的时钟线和数据线共用,所以它对时序要求很严格。比如初始化时序:
主机输出低电平,保持低电平 时间至少
480us
(该时间的时间范围可以从 480 到 960 微秒),以产生复位脉冲。
我的问题也就是出在初始时序上,下面是初始的实验例程代码(普中科技51开发板配套实验代码),只截取了DS18B20初始函数:
uchar Ds18b20Init()
{
uchar i;
DSPORT = 0; //将总线拉低480us~960us
i = 70;
while(i--);//延时642us
DSPORT = 1; //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
i = 0;
. . .
}
可以看到代码用while(i--)
实现延时,这种延时方法换了平台就不准了,更别说仿真了。不过我依旧想使用它来延时,但需要适当的调试
,起初在网上看到有人说i=73
可以,我改了后还是不行。
最后,只能使用Keil调试了:
- 首先打开代码工程,在要调试的延时函数前后设置断点。(设置方法为单击该行最左边的空白处或右键选择添加断点)
- 接着点击Debug调试按钮(或者按Ctrl+F5),开始调试。
- 点击
run
选项开始运行,程序会卡在第一个断点,此时记录一下sec
的时间,我的程序为0.00044900,即449us,接着点击Step out
跳过一个函数,直接到达while(i--)
结束的地方,此时再记录运行的时间,我的程序为875us。876-449=427,DS18B20初始化中要求的最小拉低时间为480,427小于480,所以不能完成初始化,程序也就无法正常读取温度数据。 - 知道了延时的时间不够,现在只需要适当地增大
i
的值即可(记得重新编译
再调试),我增大到80才勉强达到480us的延时。
把程序烧录到单片机后,开启仿真,终于能正常仿真了: