写字节操作函数:
void DS18B20_WriteByte(unsigned char Com)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(Com&0x01)
DS18B20_Write_1();
else
DS18B20_Write_0();
Com = Com>>1;
}
}
调用DS18B20_WriteByte函数,连在8个I/O口上的一线制总线上的8个DS18B20器件,将都会接收到同样的一个字节的数据:Com。
读数据操作函数:
unsigned char Read_buf_8ch[16];
//buffer of Read DS18B20
void DS18B20_Read2Byte(void)
{
unsigned int i;
for(i=0;i<16;i++)
{
Read_buf_8ch
= DS18B20_ReadDQ();
}
}
前面已经介绍过了,在本范例中,只读取位到DS18B20内部数据区域的前两节字的温度值数据,所以数据读取函数设计成读取两个字节的函数,即需要连续读取16个位(对应于每一个DS18B20器件来说是连续的16个位)。而将读回的数据保存于一个Read_buf_8ch(简写:Rb)的数组中,可以根据系统的接线图对读回的16个字节的数据进行分析,如下图所示:
读取DS18B20的数据时,先读高位再读低位;所以可以从上图看到,以TM2的DS18B20的数据为例,TM2的两个字节的数据由Read_buf_8ch数组的16个字节数据中的每个字节的bit2位组成。可知,完成一次数据读取的操作后,可以同时读回8个DS18B20器件的数据,在数据处理时,只需针对上图的数据结构对Read_buf_8ch数组的数据进行处理即可得到每个DS18B20器件的测温值。
2.3.3 API功能函数:
供上层应用程序直接调用的函数相对来说,是与系统的具体硬件接法没有太多的关系,只需要依照DS18B20器件的操作流程进行操作即可。在此,提供两个API的范例,分别是启动温度转换控制函数和读取温度值函数。
启动温度转换控制函数:
void DS18B20_Conver(void)
{
DS18B20_Reset();
DS18B20_WriteByte(0xcc); //Skip ROM
DS18B20_WriteByte(0x44); //启动测温
}
读取温度值函数:
void DS18B20_ReadTemp(void)
{
DS18B20_Reset();
DS18B20_WriteByte(0xcc); //Skip ROM
DS18B20_WriteByte(0xbe); //送入读取数据命令
DS18B20_Read2Byte();
}
调用读取温度值函数后,8个DS18B20器件的测温数据将保存在数组Read_buf_8ch的16个字节单元当中,还有待进行下一步的处理,方可得到对应每个DS18B20器件的测温值。下面介绍简单的处理代码片断:
char i,j;
unsigned int uiData[8];
unsigned char Mask;
//OS the resoult of Temperature
for(i=15;i>=0;i--)
{
Mask = 0x01;
for(j=0;j<8;j++)
{
uiData[j] = uiData[j]<<1;
if(Read_buf_8ch&Mask) uiData[j]++;
Mask = Mask<<1;
}
}
经过上述简单的处理,8个DS18B20器件的测温数据将保存在数组uiData当中的8个单元里,就可以根据自身程序设计的需求来对这些数据进行具体的处理了。
3 结语
本文介绍的快速查询多点DS18B20温度的设计方案,解决了串联多个器件在一线制总线上的结构导致的在查询多点温度时速度缓慢的问题,基本的设计思想是:将系统设计为在每个并行端口上连接一个DS18B20器件,利用MCU的并行端口同时对多个DS18B20进行统一的操作,实现操作多个DS18B20器件的时间等同于操作单个DS18B20器件的时间。本设计思想,可以大大减少在查询多个DS18B20测温值的时间开销,满足了实时性要求较高的系统的设计需求;同时,也省掉了烦琐的总线上多个器件序列号搜索的代码的步骤,并且节省了用于存储这些器件的序列号的存储单元,使得利用DS18B20进行多点测温的操作变得更方便、容易。
虽然本文介绍的方法是以牺牲端口资源为代价,但具体在进行系统设计时,也可以通过一些扩展端口、串转并端口、多路模拟开关等硬件电路设计来弥补这些端口资源的消耗,也可通过这些硬件电路来扩展更多的DS18B20器件(如果有必要的话)。
本文所介绍的方法已经在笔者参与设计的大型恒温系统当中应用,目前系统运行稳定、可靠