2.2 系统硬件连接
本系统方案8个DS18B20器件连接在MCU的一组端口的8个I/O口上,连线示意图如下所示:
当然,上图中的示意图并没有考虑诸如端口驱动能力、抗干扰处理等,仅表明一个逻辑的连接示意,具体在产品级的设计时会根据产品的应用做必要的处理,比如增加一些必要的电路等,此处不作为讨论的重点。
从上图可见,每个端口连接有一个DS18B20器件,也即一条一线制总线上仅有一个DS18B20器件,符合了前面所述的解决方法。实际在对DS18B20器件进行操作时,只需统一地对这一组并行端口进行操作(每个端口在同一时间输出相同的电平状态)即可。
一个端口对应一个DS18B20器件,也就表示每组端口的某一个位的读回数据状态也就是该端口所对应的器件的输出状态,所以,这样的系统里面是不需要进行每个器件的序列号搜索、匹配的操作的。可知,在对DS18B20器件进行操作时,可以使用skip ROM命令来跳过ROM序列号匹配的操作,也即在所有的DS18B20器件的ROM操作时可以使用相同的端口输出时序。
2.3 软件设计思路
总结前面所介绍的电路示意图,下面详细介绍程序设计思想。
在接下来的软件介绍中,会以C语言的例子介绍具体的编程思路,但这些代码并非就是实际中所使用的代码,仅作为逻辑性的参考,以便大家理解。这些代码是从一个产品的应用当中摘出的,而程序设计的结构也是从具体的设计当中分解出来的,供大家参考。
软件设计从最底层的与DS18B20时序相关的驱动,到与一线制总线器件处理过程控制/协议的接口函数,再上升到应用API接口函数的关系如下图所示:
在对连在一组8位端口上的8个DS18B20操作时,是同时对该组端口进行操作,也即同时对8个DS18B20器件进行同步的操作。
范例程序是根据笔者的项目当中的功能需求而设计的,不一定会适合所有人的使用方法,但程序设计思想是可以参考的,这点请使用者在参考本文时对这里的范例进行一定的取舍。下面详细介绍一个以MCS51系列单片机的应用为例的范例程序,其中约定与8个DS18B20器件进行连接的是P1端口。
2.3.1 底层时序驱动
底层时序驱动程序与DS18B20的一线制总线的协议保持一致,根据一线制总线时序的特点,设计了四个基本的函数:
总线写1时序控制函数:
void DS18B20_Write_1(void)
{
P1 = 0x00; //8个DQ 线全部设置为低电平
Delay_1us(10); //延时10us左右
P1 = 0xff; //8个DQ线全部输出高电平
Delay_1us(30); //延时30us左右
}
总线写0时序控制函数:
void DS18B20_Write_0(void)
{
P1 = 0x00; //8个DQ 线全部设置为低电平
Delay_1us(40); //延时
P1 = 0xff; //端口恢复高电平
Delay_1us(1);
}
总线读取一个数据位时序控制函数:
unsigned char DS18B20_ReadDQ(void)
{
unsigned char DQ_S=0;
P1 = 0x00; //8个DQ 线全部设置为低电平
Delay_1us(10);
P1 = 0xff; //端口置1,准备读取
Delay_1us(1); //延时待总线准备好数据
DQ_S = P1; //一次性读取8条DQ线的数据状态
P1 = 0xff; //恢复端口电平
Delay_1us(30); //延时
return DQ_S; //返回读取的值
}
在读取一个总线状态数据位的函数中,将会返回一个byte的数据,该数据的8个位正好与连接在P2端口上的8个I/O口对应,如下图所示:
总线复位时序控制函数:
void DS18B20_Reset(void)
{
unsigned char Error_Counter=0;
P1 = 0x00; //8个DQ 线全部设置为低电平
Delay_1us(500); //保持总线低电平500us
P1 = 0xff;
Delay_1us(100);
if(P1!=0x00) B20_Error = P1;//如检测到DS18B20总线响应了回复信号,则读取当前8条
//总线的状态
Delay_1us(50);
P1 = 0xff;
for(Error_Counter=0;Error_Counter<200;Error_Counter++)
{
if((P1&(~B20_Error))==(~B20_Error)) break; //如检测到总线的回复信号结
//束,则退出循环
Delay_1us(1);
}
P1 = 0xff; //恢复端口电平
Delay_1us(200); //延时 200us~~~
}
在复位时序控制的函数中,使用了B20_Error全局变量,它将会传递给上一层的数据处理函数作为判断当前8个I/O口所接的DS18B20是否正常工作,或者是否在各自的总线上。
2.3.2 操作协议相关的函数
分析DS18B20的一线制总线控制命令,可以提炼出两个最基本的操作函数,一个是写一个byte数据至DS18B20器件,另一为读取DS18B20器件的数据。而在本文的范例程序当中,仅仅为了提取DS18B20器件的转换完后的温度值,所以在读取DS18B20的数据时,仅读取存放在数据地址前两个字节的温度数据,而不读取其它字节的数据,包括CRC校验值也没有进行读取,供参考。