DS18B20的温度转换与读取流程
- DS18B20复位
- 写入字节0xcc,跳过ROM指令
- 写入字节0x44,开始温度转换
- 延时700~900ms
- DS18B20复位
- 写入字节0xcc,跳过ROM指令
- 写入字节0xbe,读取高速暂存器
- 读取暂存器的第0字节,即温度数据的LSB
- 读取暂存器的第1字节,即温度数据的MSB
- DS18B20复位。表示读取数据结束
IAP15F2K60S2的运算速度比51要快12倍,给的底层驱动代码一般是51的,使用发现温度不准,只需要把onewire.c驱动代码中的延时增大10倍或者12倍就可以了。
#include <STC15F2K60S2.H>
#include <absacc.h>
#include <onewire.h>
void delay(unsigned int t);
void delayTemp(unsigned int t);
void delaySMGall(unsigned char dat);
void delaySMGbit(unsigned char w,unsigned char n);
void delaySMGtemp();
void Read_DS18B20Temp();
unsigned char SMGNoDot_CA[10]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x90,0x90}; //无小数点
unsigned char SMGDot_CA[10]={
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //显示小数点
unsigned int temp=0; //存放温度数据
void main()
{
XBYTE[0xa000]=0x00;
while(1)
{
Read_DS18B20Temp();
delaySMGtemp();
}
}
void Read_DS18B20Temp()
{
unsigned char LSB; //温度的低八位
unsigned char MSB; //温度的高八位
init_ds18b20(); //1.DS18B20复位
Write_DS18B20(0xcc); //2.写入字节0xcc,跳过ROM指令
Write_DS18B20(0x44); //3.写入字节0x44,开始温度转换
delayTemp(1000); //4.延时700~900ms
init_ds18b20(); //5.DS18B20复位
Write_DS18B20(0xcc); //6.写入字节0xcc,跳过ROM指令
Write_DS18B20(0xbe); //7.写入字节0xbe,读取高速暂存器
LSB=Read_DS18B20(); //8.读取暂存器的第0字节,即温度数据的LSB
MSB=Read_DS18B20(); //9.读取暂存器的第1字节,即温度数据的MSB
init_ds18b20(); //10.DS18B20复位。表示读取数据结束
temp=MSB;
temp=(temp<<8)|LSB;
temp>>=4; //移除小数部分
/*if((temp&0xf800)==0x0000) // 有小数,判断温度是不是正数 正数temp=0567, 与上f800等于0000
{
temp>>=4;
temp=temp*10;
temp=temp+(LSB&0x0f)*0.0625;
}*/
}
void delaySMGall(unsigned char dat)
{
XBYTE[0xe000]=0xff;
XBYTE[0xc000]=dat;
}
void delaySMGbit(unsigned char w,unsigned char n) //第w个数码管显示数字n
{
XBYTE[0xe000]=0xff;
XBYTE[0xc000]=0x01<<w;
XBYTE[0xe000]=n;
}
void delaySMGtemp() //显示温度
{
//显示小数部分
/*delaySMGbit(7,SMGNoDot_CA[temp%10]);
delay(100);
delaySMGbit(6,SMGDot_CA[(temp/100)%10]);
delay(100);
delaySMGbit(5,SMGNoDot_CA[temp/100]);
delay(100);*/
//只显示整数
delaySMGbit(7,SMGNoDot_CA[temp%10]);
delay(100);
delaySMGbit(6,SMGNoDot_CA[temp/10]);
delay(100);
delaySMGbit(5,0xff);
delay(100);
//只需要3个数码管显示温度,其他数码管不亮
delaySMGbit(4,0xff);
delay(100);
delaySMGbit(3,0xff);
delay(100);
delaySMGbit(2,0xff);
delay(100);
delaySMGbit(1,0xff);
delay(100);
delaySMGbit(0,0xff);
delay(100);
delaySMGall(0xff);
}
void delayTemp(unsigned int t)
{
while(t--)
{
delaySMGtemp();
}
}
void delay(unsigned int t)
{
while(t--);
}
底层驱动代码
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
日 期: 2011-8-9
*/
#include "reg52.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
while(t--);
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(50);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(50);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(50);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(120);
DQ = 0;
Delay_OneWire(800);
DQ = 1;
Delay_OneWire(100);
initflag = DQ;
Delay_OneWire(50);
return initflag;
}
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
unsigned char rd_temperature(void); //; ;
bit init_ds18b20(void);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
#endif