一.硬件部分
GND脚接地;
DQ脚接P03,外加4K7上拉电阻;
VCC脚接3.3v供电;
二.软件部分
1.配置P03为准准双向 IO类型:
void Init_power_gpio(void)
{
P03_Quasi_Mode; //DS18B20
P03=1;
}
2.配置定时器2(可任意选用定时器):
void Timer2_init(void)
{ //系统上电默认16M高速时钟源使能,并作为系统时钟
clr_TR2; //TR2停止时写入重新装载值
TIMER2_DIV_16; //使用1/16分频 一秒震动为16000000/16
TIMER2_Auto_Reload_Delay_Mode; //配置为自动重装载模式
RCMP2L =(65536-1)/256;
RCMP2H =(65536-1)%256;
TL2 = 0; //重装载值
TH2 = 0;
// set_ET2; //使能定时器3中断
// set_EA; //使能所有中断
set_TR2; //使能定时器3
}
3.初始化:
/*----------------------------------------------------------
函数名称:void Init_DS18B20(void)
函数功能:初始化
描述:480-960微妙低电平,然后释放为高电平 完成一次复位
--------------------------------------------------------*/
void Init_DS18B20(void)
{
P03=1; //起始位高电平
TL2=0;
TH2=0;
while((TH2*256+TL2)<900);
P03=0; // 拉低
TL2=0;
TH2=0;
while((TH2*256+TL2)<500);// 延时约500us, 符合协议要求480-960微秒的低电平脉冲
P03=1; //产生一个上升沿, 进入等待应答状态
}
4.
/*----------------------------------------------------------
函数名称:void Wait_DS18B20(void)
函数功能:等待应答
描述:
--------------------------------------------------------*/
void Wait_DS18B20()
{
while(P03); //等待应答
while(~P03) //检测到应答脉冲
// {
// printf("应答\n");
// }
TL2=0;
TH2=0;
while((TH2*256+TL2)<70);
}
5.
/*----------------------------------------------------------
函数名称:bit ReadOneBit(void)
函数功能:读取一字节
读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
之后DS18B20则会输出持续一段时间的一位数据
-------------------------------------------------------*/
bit ReadOneBit(void)
{
bit b;
P03 = 0;
TL2=0;
TH2=0;
while((TH2*256+TL2)<10); //延时约10us, 符合协议要求至少保持1us
P03 = 1;
TL2=0;
TH2=0;
while((TH2*256+TL2)<20); //延时约20us, 符合协议要求的至少延时15us以上
b = P03;
TL2=0;
TH2=0;
while((TH2*256+TL2)<70); //延时约70us, 符合读时隙不低于60us要求
return b;
}
6.
/*********************************************
函数功能:向DS18B20读一字节数据
入口参数:dat
***********************************************/
unsigned char ReadOneByte()
{
unsigned int i;
unsigned char j, dat;
dat = 0;
for(i=0; i<8; i++)
{
j = ReadOneBit();
//最先读出的是最低位数据
dat = (j << 7) | (dat >> 1);
}
return dat;
}
7.
/*********************************************
函数功能:向DS18B20写一字节数据
入口参数:dat
描述:写0:拉低1us-15us后拉低最少60,最长120us,再释放高电平
写1:拉低1us-15us后释放高最少60,最长120us直到周期结束
***********************************************/
void WriteOneByte(unsigned char dat)
{
unsigned char j;
bit b;
for(j = 0; j < 8; j++)
{
b = dat & 0x01;
dat >>= 1;
//写"1", 拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
if(b)
{
P03 = 0;
TL2=0;
TH2=0;
while((TH2*256+TL2)<3); //拉低约3usus, 符合协议要求1~15us内,提示写开始
P03 = 1;
TL2=0;
TH2=0;
while((TH2*256+TL2)<70); //延时约70us, 符合写时隙不低于60us要求
}
else //写"0", 将DQ拉低60us~120us
{
P03 = 0;
TL2=0;
TH2=0;
while((TH2*256+TL2)<70); //延时约70us, 符合写时隙不低于60us要求
P03 = 1;
TL2=0;
TH2=0;
while((TH2*256+TL2)<3); //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了
}
}
}
8.
/*********************************************
函数名:SendChangeCmd
参数:
返回值:
功能:向DS18B20发送温度转换命令
***********************************************/
void SendChangeCmd()
{
Init_DS18B20(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化
Wait_DS18B20(); //等待DS18B20应答
TL2=0;
TH2=0;
while((TH2*256+TL2)<200); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
WriteOneByte(0xcc); //写入跳过序列号命令字 Skip Rom
WriteOneByte(0x44); //写入温度转换命令字 Convert T
}
9.
/*********************************************
函数名:SendReadCmd
参数:
返回值:
功能:向DS18B20发送读取数据命令
***