51单片机温度传感器

51单片机总结—— DS18B20数字温度传感器

单总线时序和注意事项:
单总线信号类型:复位脉冲、存在脉冲、写0、写1、读0、读1。所有这些信号除存在脉冲由DS18B20发出的以外其他信号都由总线控制器发出。
数据传输总是从最低有效位开始
电路连接图示

执行序列
通过单线总线端口访问DS18B20的协议如下:
步骤1. 初始化
步骤2. ROM操作指令
步骤3. DS18B20功能指令
温度转换命令
读取暂存器命令

电路连接图示
在这里插入图片描述
程序中使用:
在这里插入图片描述
**

程序内容:

初始化时序
初始化时序里面包含了复位DS18B20和接收DS18B20返回的存在信号。
主机和DS18B20做任何通讯前都需要对其初始化。初始化期间,总线控制器拉低总线并保持480us以上挂在总线上的器件将被复位,然后释放总线,等到15-60us,此时18B20将返回一个60-240 us之间的低电平存在信号。
复位脉冲和存在脉冲时序图
在这里插入图片描述
程序中使用:
在这里插入图片描述
写时序:
写时序分为写0时序和写1时序。
总线控制器通过控制单总线高低电平持续时间从而把逻辑1或0写DS18B20中。
总线控制器要产生一个写时序,必须将总线拉低最少1us,产生写0时序时总线必须保持低电平60~120us之间,然后释放总线,产生写1时序时在总线产生写时序后的15us内允许把总线拉高。注意:2次写周期之间至少间隔1us。
在这里插入图片描述
程序中的使用:
在这里插入图片描述
读时序:
读时序分为读0时序和读1时序。
总线控制器通过读取由DS18B20控制的总线高低电平接收DS18B20数据。
总线控制器要产生一个读时序,必须将总线拉低至少1us,然后释放总线,在读信号开始后15us内总线控制器采样总线数据,读一位数据至少保持在60us以上。注意:2次读周期之间至少间隔1us。
在这里插入图片描述
程序中的使用:
在这里插入图片描述
主函数内容配置
DS18B20暂存器
在这里插入图片描述
在这里插入图片描述
配置寄存器图表
在这里插入图片描述
DS18B20功能指令:
温度转换指令(44h)
这条命令用以启动一次温度转换。温度转换指令被执行,产生的温度转换结果数
据以2个字节的形式被存储在高速暂存器中,而后DS18B20保持等待状态。
读暂存器指令(BEh)
这条命令读取暂存器的内容。读取将从字节0 开始,一直进行下去,直到读完暂存
器所有字节,如果不想读完所有字节,控制器可以在任何时间发出复位命令来中止
读取。
写暂存器指令(4Eh)
这条命令向DS18B20 的暂存器写入数据,开始位置在TH 寄存器(暂存器的第2
个字节),接下来写入TL 寄存器(暂存器的第3 个字节),最后写入配置寄存器
(暂存器的第4 个字节)
拷贝暂存器指令(48h)
这条命令把TH,TL 和配置寄存器(第2、3、4 字节)的内容拷贝到EEPROM 中。

程序中的使用(用在主函数中):
在这里插入图片描述
程序实现:
#include <reg52.h>
#include <intrins.h>
#define MAIN_Fosc 11059200UL //宏定义主时钟HZ
//自定义类型名
typedef unsigned char INT8U;
typedef unsigned char uchar;

typedef unsigned int INT16U;
typedef unsigned int uint;

//硬件接口位声明
sbit DS = P2^2; //DS18B20单总线
sbit du = P2^6; //数码管段选
sbit we = P2^7; //数码管位选

void Display(INT16U Value);

//共阴极数码管段选码
uchar code table[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //不带小数点0-9
//数码管位选码
uchar code T_COM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//第1,2,3,4,5,6,7,8位

void Delay_Ms(INT16U ms) //毫秒延时
{
INT16U i;
do{
i=MAIN_Fosc/96000;
while(–i); //96T per loop
} while(–ms);
}
//us延时函数,执行一次us–需要6.5us,进入一次函数需要11.95us
void Delay_us(uchar us)
{
while(us–);
}

/单总线初始化时序/
bit ds_init()
{
bit i;//声明一个变量存储(返回的信号值)
DS = 1;//总线置于高电平
nop();//空指令延时?
DS = 0;//拉低总线480us以上
Delay_us(75); //499.45us,挂接在总线上的18B20将会全部被复位
DS = 1;//释放总线
Delay_us(4);//15~60us,延时37.95us,等待18B20发回存在信号
i = DS;//(0 or 1)
Delay_us(20);//60~240us, 141.95us
DS = 1;//释放单总线
nop();//延时等稳定
return (i);//若1=0,则DS1802存在在总线上,并且准备好了,可以对其操作
}
/写一个字节,写时序/
void write_byte(uchar dat)//把要写的数据赋给形参dat,然后传递进来(一次一个字节,要循环八次)
{
uchar i;
for(i=0;i<8;i++)
{
DS = 0; //拉低总线
nop();//小延时,产生写时序
DS = dat & 0x01;//数据传输总是从最低有效位开始的,在这里即是从数据的最低位开始(eg:00000001&00000001=00000001 00000000&00000001=00000000)
Delay_us(10);//写0时序,低电平保持60~120us,写1时序,60us以上,此处延时76.95us,同时满足0和1
DS = 1;//释放总线,准备下一次写入数据
nop(); //延时大于1us即可
dat >>= 1;//写入第一个数据以后,dat右移一位(此处为何右移,明白了,使第二位,三位。。。挪到一位与1&)
}
}
/读一个字节/
uchar read_byte()
{
uchar i,j,dat;//循环变量,存储每读一位时用到的变量,存储一个字节的变量
for(i=0;i<8;i++)
{
DS = 0;//拉低单总线
nop();//小延时,此处要求1us,产生读时序
DS = 1;
nop();//释放总线
j=DS;//用j获取DS上的值
Delay_us(10);//76.95us,此处要求60us以上
DS = 1;
nop();//释放总线,又把总线交给从机DS180控制,方便下一次数据的读取
dat = (j<<7)|(dat>>1);//j左移七位,就将字节的最低位,移到了最高位,与上dat右移一位,把j的最高位写入dat最高位,依次
}
return (dat);//读字节

}

void main()
{
uint i; //温度两个字节
uchar L,M;//存取温度的低字节和高字节
while(1)
{
ds_init();//初始化DS18B20
write_byte(0xcc);//发送跳跃ROM指令
write_byte(0x44);//发送温度转换指令
ds_init();//初始化DS18B20
write_byte(0xcc);//发送跳跃ROM指令
write_byte(0xbe);//读取DS18B20暂存器值
L = read_byte();//读第一个字节
M = read_byte();//读第二个字节,只读两个字节是因为只需要知道温度值
/若为负温度时
M=0xfc;
L=0x90;
i=M;
i<<=8;
i|=L;
if(M>=0x08) //判断是否为负数
{
i=~i+1; //负数是以补码的形式存放的需要我们需要取反加一
s=0x40; //显示负数符号
}
else s=0;//为正数则不显示
temp=i
0.062510000;//浮点型数据转换
Display(temp);
/

	i = M;
	i<<=8;//左移八位,将M放到i的高八位
	i |=L;//把L写入i的低八位
	i = i * 0.0625 * 10 + 0.5;//将二进制换算成实际温度,10是为了保留小数点后一位,到时候在数码管上手动加小数点,0.5是为了四舍五入
	Display(i);
}

}
void Display(INT16U Value) //由于需要显示的数大于一个字节,所有形参需为int
{
du=0;//关闭段选
P0=table[Value/100]; //数码管显示百位
du=1; //打开段选
du=0; //关闭段选

we=0;	 //关闭位选
P0=T_COM[0];		   //选择第一位数码管
we=1;  //打开位选
Delay_Ms(3);



du=0;//关闭段选
P0=table[Value%100/10]|0x80; //数码管显示十位
du=1;	//打开段选
du=0;	//关闭段选

we=0;	 //关闭位选
P0=T_COM[1];		   //选择第二位数码管
we=1;  //打开位选
Delay_Ms(3);



du=0;//关闭段选
P0=table[Value%10]; //数码管显示个位
du=1;	//打开段选
du=0;	//关闭段选

we=0;	 //关闭位选
P0=T_COM[2];		   //选择第三位数码管
we=1;  //打开位选
Delay_Ms(3);

}

附表
在这里插入图片描述
谢谢!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值