在会使用数码管的基础上,可以实现用单总线温度传感器DS18B20实现多点即时测温,这一次实验只简单的尝试一下单点即时测温而已。
关于7seg-ca的使用在《数码管的控制工程规划》中有总结。这次实验关键是总机与DS18B20的通信协议的编制.
DS18B20通过时序来与总线进行通信,最主要的分为三个步骤:
1. 初始化DS18B20
2. 写入控制命令(如转换温度,准备读出温度等)
3. 读出温度
一) 初始化
对于DS18B20,规定了自身的初始化方式,编制的初始化的代码如下:
void InitDs18b20()
{
unsigned char cnt=0;
DQ=1;
Delay(1);//延时5us左右
DQ=0;
Delay(250);//延时505左右
DQ=1;
Delay(100);//延时205微秒左右
}
代码参考了网络上的程序。
在DS18B20技术手册中,初始化的要求规则如下
(1) 先将数据线置高电平“1”。
(2) 延时(该时间要求的不是很严格,但是尽可能的短一点)
(3) 数据线拉到低电平“0”。
(4) 延时750微秒(该时间的时间范围可以从480到960微秒)。
(5) 数据线拉到高电平“1”。
(6) 延时等待(如果初始化成功则在15到60毫秒(应当是微秒)时间之内产生一个由DS18B20所返回的低电平“0”。据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。
(7) 若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。
(8) 将数据线再次拉高到高电平“1”后结束。
不同的资料中使用的方法不忘全相同,但是,时序总体上都是按着示意图编制的。分为两大步骤:主机发出复位信号持续480~900秒,释放总线,在之后的240us时间内,DS18B20发出存在电平1,持续存在.
二)写入控制命令
写入控制命令与写时序的规定有关。设计的程序如下:
void WriteByte(unsigned char a)
{
unsigned char i;
for(i=8; i>0; i--)
{
DQ=0;
NOP;//尽量短的时间
DQ=a & 1;
Delay(10);
DQ=1;//释放总线
Delay(1);//延时.
a>>=1;
}
}
时序一个重要的要求是保证整个时序的间隔是60us。
一开始的拉低电平,非常重要,表明接下来主机与18B20之间要开始通信。
在接下来的极短的时间内,主机必须把信息传给总线,DS18B20在时序的后39us对总线采样读数,所以主机要保证有足够的延时。
60us结束时,释放总线.
此外,DS18B20在写入控制命令0X44进行温度转换后还必须进行一次初始化,然后写入读温度命令。所以主程序是如下的:
InitDs18b20();
WriteByte(0xcc);//跳过ROM。
WriteByte(0x44);//温度转换.
InitDs18b20();
WriteByte(0xcc);
WriteByte(0xbe);//读温度命令
a=ReadByte();//读取温度,低位
b=ReadByte();//读取温度,高位
三)读温度
读温读,就是读DS18B20内存中的16位的存储空间上的内容
unsigned char ReadByte()
{
unsigned char a=0,i;
for(i=8; i>0; i--)
{
DQ=0;//1
NOP;
a>>=1;
DQ=1;//1 释放总线
Delay(1);
if(DQ) a|=0x80;
Delay(10);
}//确保该时序的时间为60us
return a;
}
首先有一点要明确,DS18B20的通信协议数据传输都是低位在前,不论是写命令还是读温度。这样就能理解if(DQ) a|=0x80; a>>=1;这两条代码。
读数据时与写数据,命令格式基本相同,拉低电平,表示主机做好了接受数据的准备,在15us内,主机完成数据的读取采样,之后的时间全部留空,以保证读数的惟一准确性。时序持续的时间也是60us。
|