/*-------------------------------------------------------------------------------------
驱动名称:I-WIRE DQ18B20 底层驱动程序
测试范围:-55°~125°
精 度: >0.1°
署 名:先永 完成时间:2009、2、22
功 能:I-WIRE底层协议 18b20读写操作
说 明:通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值
-------------------------------------------------------------------------------------*/
#include <at89x51.h>
#include "7seg.c"
#include "com.c"
#define uchar unsigned char
#define uint unsigned int
#define DQ P2_7 //DS18B20管脚定义
bit X=0; //复位S18B20标志位 X=0成功 X=1错误;
/*-----------------------I-WIRE底层函数(可移植)-----------------------------------*/
void delay_us(int cnt); // 时间=16*cnt+24 us
void Init_1Bus(void); //复位
uchar Read_Bus_bit(void); //读一位
void Write_Bus_bit (bit bitvalue); //写一位
/*-----------------------应用层函数 (DS18B20)------------------------------------*/
//延时函数, 例i=10,则大概延时10ms.
void delay(unsigned char i)
{
unsigned char j, k;
for(j = i; j > 0; j--)
{
for(k = 125; k > 0; k--);
}
}
//==========================================================================
//函数功能:产生一定延时,时序发生
//晶 振:11.0592 M
//入口参数:时间=16*cnt+24 us
//==========================================================================
void delay_us(int cnt)
{
int i;
for(i=0;i<cnt;i++);
}
//==========================================================================
//函数功能:复位脉冲
//总线协议:1.主机拉低 480us≤DQ≤960us
// 2.主机等待 15us≤DQ≤60us
// 3.从机应答 60us≤DQ≤240us 拉低DQ
//说 明:4.从机接收 480us≤DQ(时间=主机等待+从机应答)
// 此程序采用较宽的纠错时序范围(不一错)
//==========================================================================
void Init_1Bus(void)
{
DQ=0;
delay_us(36); //延时600us
DQ=1; //释放总线
delay_us(4); //从机等待
X=DQ; //检测DQ18B20标志位
delay_us(30); //延时>480us 复位结束
}
//==========================================================================
//函数功能:向总线 写"1"和写"0"
//总线协议:1.主机拉低电平 60us≤DQ≤120us
//==========================================================================
void Write_Bus_bit (bit bitvalue)
{
DQ=0;
if(bitvalue==1)
{
DQ=1;
}
delay_us(4); //等待写时隙结束 (90us)
DQ=1;
}
//==========================================================================
//函数功能:在总线上读1位
//总线协议:主机发送读指令 0—1;从机应答长1 或者长0
//==========================================================================
uchar Read_Bus_bit(void)
{
uchar i;
DQ=0;
DQ=1; //主机拉低电平 等待从机反馈
for(i=0;i<3;i++); //time need 1us≤DQ≤15us
//时间还需要用示波器观看2009、5、6
//实际测试结果为12us
i=DQ; //Master samples
delay_us(3); //读时序>60us
return i;
}
//==========================================================================
//函数功能:写一字节总线, 通过调用Write_Byte_to_1Bus()
//总线协议:数据发送高位在前
//==========================================================================
void Write_Bus_Byte(uchar write_data)
{
uchar i;
for(i=0;i<8;i++) //循环移入8位 低位在前
{
DQ=(bit)(write_data&0x01);
Write_Bus_bit(DQ);
write_data>>=1; //保持长点的高定平
}
delay_us(5); //等待时隙结束
}
//==========================================================================
//函数功能:读取一字节数据, 通过调用Write_Byte_to_1Bus()
//总线协议:数据接收低位在前
//==========================================================================
uchar Read_Bus_Byte (void)
{
uchar i,data_temp=0;
for(i=0;i<8;i++) //循环读取8位 低位在前
{
if(Read_Bus_bit()==1)
{
data_temp=data_temp|(0x01<<i);
}
}
delay_us(5); //等待时隙结束
return data_temp;
}
//获取当前温度值
void Read_18B20()
{
unsigned int i; //存放温度数值
Init_1Bus(); //初始化DS18B20
delay(1); //延时1ms
Write_Bus_Byte(0x33); //写入直接访问ROM命令字
for(i=0;i<8;i++)
{
send_char_com(Read_Bus_Byte());
}
send_char_com(0x88);
}
//==========================================================================
//函数功能:
//入口参数:
//出口参数:
//总线协议:
//说 明:
//==========================================================================
main()
{
uint i;
Init_Com();
while(1)
{
Read_18B20();
display (i);
}
}