复习单片机:温度计DS18B20代码部分(内含代码部分详解+示意图)

简介: 复习单片机:温度计DS18B20代码部分(内含代码部分详解+示意图)

1.总思路:


DS18B20 的典型温度读取过程为:1.复位→2.发 SKIP ROM 命令(0XCC)→3.发开始转 换命令(0X44)→4.延时→5.复位→6.发送 SKIP ROM 命令(0XCC)→7.发读存储器命令 (0XBE)→8.连续读出两个字节数据(即温度)→9.结束。


2.初始化时序函数:


3bf9a4746ac1418e9635b449c44c2d75.png

//初始化
void ds18b20_reset(void)
{
DS18B20_PORT=0;//第一步拉低
delay_10us(75);//第二步延时
DS18B20_PORT=1;//第三步拉高
delay_10us(2);//第四步延时
}
//如果有相应(包括拉低,延时,拉高延时),返回0,没有相应返回1
u8 ds18b20_check(void)
{
u8 time_temp=0;//第五步拉低
//相应的拉低判断和延时时间长短判断
while(DS18B20&&time_temp<20)//用while循环判断,如果时间过长,则为没有相应
{ //意思是在200us之内可以持续等待ds18b20拉低
time_temp++;
delay_10us(1);
}
if(time_temp>=20) return 1;//确定没有相应
time_temp=0;
delay_10us(2);
while((!DS18B20)&&(time_temp<20))
{
time_temp++;
delay_10us(1);
}
if(time_temp>=20) return 1;
return 0;
}

3.写时序:


2143f5d165df4bbd865bcd2a29d5125f.png


//写时序
void ds18b20_write_type(u8 dat)
{
u8 i=0;
u8 temp=0;//为了接收dat并按位与传递
for(i=0;i<8;i++)
{
temp=dat&0x01;//得到dat最低位方法:dat与0x01进行按位与
dat>>=1;//每次移动一个位
if(temp)//写1时序时
{
DS18B20_PORT=0;//第一步,拉低
_nop_();_nop_();//第二步,延时,因为只需要2us,则只能用2us
DS18B20_PORT=1;//第三步,拉高
delay_10us(6);//第四步,延时
}
else//写0时序时
{
DS18B20_PORT=0;//第一步,拉低
delay_10us(6);//第二步,延时
DS18B20_PORT=1;//第三步,拉高
_nop_();_nop_(); //第四步,延时
}
}
}

4.读时序:

ac6badb7b9114e44bff475649a447bb3.png


//读时序---一个字节


u8 ds18b20_read_bit(void)
{
u8 dat=0;//返回dat来判断读一还是零
DS18B20_PORT=1;//准备工作
_nop_();_nop_();
DS18B20_PORT=0;//第一步,拉低
_nop_();_nop_();//第二步,延时
if(DS18B20_PORT) dat=1;//此处是对1和0的判断,用if比较好
else dat=0;//如果DS18B20是低,则返回的dat为0
delay_10us(45);
}

//读时序---将每个字节都写

u8 ds18b20_write_type(void)
{
u8 i=0;//for用到
u8 dat=0;
u8 temp=0;
for(i=0;i<7;i++)
{
temp=ds18b20_read_bit();//将读一个字节的值传递给temp
dat=temp<<7;//将temp左移7位,传递给dat
dat>>=dat;//向右移动一位,给下一个数做铺垫
}
return dat;//返回读时序每一位的1或0
}


5.温度读取过程:


dc9905c8030e47e1a651faca33592cb8.png


DS18B20 的典型温度读取过程为:1.复位→2.发 SKIP ROM 命令(0XCC)→3.发开始转 换命令(0X44)→4.延时→5.复位→6.发送 SKIP ROM 命令(0XCC)→7.发读存储器命令 (0XBE)→8.连续读出两个字节数据(即温度)→9.结束。


//DS18B20温度读取过程函数


float ds18b20_read_temperture(void)
{
float temp;//读取并传递最终的值
u8 dath=0;//高字节,即高八位
u8 datl=0;//低字节,即第八位
u16 value=0;
ds18b20_reset();//第一步,复位
ds18b20_check();// 检测
ds18b20_write_byte(0xcc);//第二步,发0XCC命令
ds18b20_write_byte(0xbe);//第三步,发0x44
//第四步延时,可跳过,因为写函数里面自带延时
ds18b20_reset();//第五步,复位
ds18b20_check();// 检测
ds18b20_write_byte(0xcc);//第六步,发0XCC命令
ds18b20_write_byte(0xbe);//第七步,发0x44
//第八步 读两个字节,需要第八位+高八位,
//高八位按位向左移八位才是真正的高八位,
//并将此时的高八位和第八位相加,即是16位数据value
//之后判断符合位,如果是负温度,需要&0xf800,
//之后按位取反再+1,所得结果*0.0625,
//因为温度是负数,所以注意带负号
datl=ds18b20_read_byte();//第八步,读低字节+
dath=ds18b20_read_byte();//高字节
value=(dath<<8)+datl;//合并为16位数据
if((value&0xf800)==0xf800)//判断符号位,负温度
{
value=(~value)+1; //数据取反再加1
temp=value*(-0.0625);//乘以精度
}
else //正温度
{
temp=value*0.0625;
}
return temp;
}


相关文章
|
6月前
|
存储 算法 编译器
如何优化单片机程序里面的C代码方法
如何优化单片机程序里面的C代码方法
53 0
|
3月前
|
C语言
【51单片机】LCD1602显示字符串,时间、时间+按键校准、秒表计时的功能代码。
【51单片机】LCD1602显示字符串,时间、时间+按键校准、秒表计时的功能代码。
|
3月前
|
C语言
51单片机汇编语言流水灯代码
51单片机汇编语言流水灯代码
|
6月前
|
传感器
51单片机循迹小车原理介绍和代码示例
51单片机循迹小车原理介绍和代码示例
51单片机循迹小车原理介绍和代码示例
|
6月前
|
传感器
51单片机矩阵键盘超详解!(内含LCD1602代码)
51单片机矩阵键盘超详解!(内含LCD1602代码)
95 0
【51单片机】自定义动态数码管显示(设计思路&原理&代码演示)
【51单片机】自定义动态数码管显示(设计思路&原理&代码演示)
【51单片机】自定义静态数码管显示(设计思路&代码演示)
【51单片机】自定义静态数码管显示(设计思路&代码演示)
|
6月前
|
C++
【51单片机】添加模块代码的常见问题(图示&代码演示)
【51单片机】添加模块代码的常见问题(图示&代码演示)
【51单片机】烧写教程:将代码下载到单片机中(图示&解析)
【51单片机】烧写教程:将代码下载到单片机中(图示&解析)
【51单片机】静态数码管显示(设计思路&原理&代码演示)
【51单片机】静态数码管显示(设计思路&原理&代码演示)