若有错误欢迎指正,共同学习。本次经验分享当成自己的一次学习记录。
使用的开发板为普中开发板,stc89c52,晶振频率为11.0592MHZ。
单总线的初始化时序相当严格,精确到了微秒。水平所限,时序不再讲。
这个文件是onewire单总线时序驱动代码(蓝桥杯的老版本驱动)。
链接:https://pan.baidu.com/s/1R-gofrbI-X0qwNqjS_SqOQ
提取码:gxfc
关于ds18b20的温度部分提取,我用的方法稍微有点复杂,不过感觉很笨。
首先是提取ds18b20的前两个字节,但并没有直接处理,仅作提取,因为我感觉小数部分处理起来比较麻烦。
ds18b20.c
#include "ds18b20.h"
#include "onewire.h"
#include "reg52.h"
unsigned int Ds18b20_Read_T(void)
{
unsigned char t1,t2;
unsigned int temp;
Init_DS18B20();
Write_DS18B20(OW_SKIP_ROM);
Write_DS18B20(DS18B20_CONVERT);
Init_DS18B20();
Write_DS18B20(OW_SKIP_ROM);
Write_DS18B20(DS18B20_READ);
t1=Read_DS18B20();
t2=Read_DS18B20();
//****数据转换1****
temp=t2;
temp<<=8;
temp|=t1;
return temp;
}
因为我使用的开发板不能对数码管对应引脚直接操作(需由74H138译码器和P2引脚控制),如下图。
这部分代码不多说。
那么直接转到对上述ds18b20数据的处理。
void ds18b20_showInt(unsigned int temp)//三位整数
{
smg_show(2,temp/100);//数码管的两个参数依次是位,值
Delay2ms();
smg_show(3,temp/10%10);
Delay2ms();
smg_show(4,temp%10);
Delay2ms();
smg_show(4,10);
Delay2ms();
}
void ds18b20_showFloat(unsigned int temp0)//保留了两位小数
{
smg_show(5,temp0/1000);//4位十进制整数的千位
Delay2ms();
smg_show(6,temp0/100%10);//4位十进制整数的百位
Delay2ms();
}
void ds18b20_convert_show()//处理获得的ds18b20数据
{
//数据转换
u16 t3,temp;
float tt;
temp=Ds18b20_Read_T(); //首先获得温度数据
t3=temp&0x000F; //单独提取小数位
temp>>=4; //右移四位去掉小数位
if(temp>128)
{temp=~temp+1;smg_show(1,12);Delay2ms();}
//负数显示这部分没有实际测试过
//smg_show(1,12);是在第一位显示负号
ds18b20_showInt(temp); //显示整数位
tt=t3*0.0625;
//四位小数位对应十进制最大值为(1+2+4+8)*0.0628=0.9375
//小数位的四个位,第一位0.0625*1,第2位0.0625*2,第3位对应0.0625*4,第四位对应0.0625*8
ds18b20_showFloat(tt*10000);//这里直接*10000 转化成十进制整数
}
关于温度值负数的处理是:使用补码形式输出,我们只需要对这个字节进行取反加1后就是这个负温度的绝对值,一个符号标记(数码管的'-')告诉输出函数这是个负温度需要显示负。