仪器社区

单片机控制DS18B20的主程序

xjq469 2016-06-13
我只想知道单片机读取DS18B20的程序,不需要数码管或者液晶屏显示,该怎么编程啊?... 我只想知道单片机读取DS18B20的程序,不需要数码管或者液晶屏显示,该怎么编程啊?
评论
全部评论
累累的老巢
/***温度传感器DS18B20驱动——火柴天堂作品-20120622***/
/***源程序硬件环境:52单片机,12MHz晶振,P37接 DS18B20 数据引脚,非寄生电源(即外部电源接法)***/
/***DS18B20 测量温度范围:-55℃~+125℃***/

#define DS18B02_H
#include"reg52.h" //包含52头文件
#include"DS18B20.h" //包含DS1302宏定义文件

sbit DS18B20_DQ=P3^7; //定义 DS18B20 数据口
#define DQ_High DS18B20_DQ=1 //拉高 数据口
#define DQ_Low DS18B20_DQ=0 //拉低 数据口
uchar code CRC_List[256]={//8540 CRC-8校验列表
//x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf,
0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, //0x
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, //1x
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, //2x
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, //3x
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, //4x
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, //5x
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, //6x
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, //7x
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, //8x
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, //9x
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, //ax
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, //bx
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, //cx
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, //dx
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, //ex
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};//fx

void Delay(uint delay_time) //延时函数,非精确延时,Fosc=12MHz
{
while(delay_time--);
}

uchar CRC_18b20(uchar *buf_p,uchar leng) //CRC校验函数,*buf_p指向待检验数组,leng进行校验的个数,若含CRC码进行校验,结果应为0
{
uchar i,crc_data=0;
for(i=0;i return crc_data;
}

void Reset_18b20() //DS18B20复位函数
{
DQ_Low; //拉低 数据口
Delay(80); //==延时500us==
DQ_High; //拉高 数据口,等待DS18B20回应
Delay(2); //==延时16~60us==
if(DS18B20_DQ) Delay(3); //若DS18B20无回应,再等待一段时间
//if(DS18B20_DQ) return FALSE; //依然无回应,返回 复位失败(带布尔量返回时使用)
while(!DS18B20_DQ); //若有回应,等待回应结束
//return TRUE; //返回 复位成功
}

uchar Read_18b20() //DS18B20读函数
{
uchar i,temp=0;
for(i=0;i<8;i++) //读8个位
{
DQ_Low; //拉低 数据口 ==延时1us==
DQ_High; //拉高 数据口,
//Delay(1); //==延时1us==
if(DS18B20_DQ) temp|=1< Delay(2); //==延时==
}
return temp; //返回 读取结果
}

void Write_18b20(uchar comm) //DS18B20写函数
{
uchar i;
for(i=0;i<8;i++) //写8个位
{
DQ_Low; //拉低 数据口
//Delay(1); //==延时5us==
DS18B20_DQ=comm&0x01; //将数据Z低位赋于 数据口
//if(comm &(1< Delay(2); //==延时50us 以上==
DQ_High; //拉高 数据口
comm >>= 1; //将下一位发送数据移到Z低位
//Delay(1); //恢复时间
}
}
//uchar ReadB20Power() //读DS18B20电源模式,返回:0 寄生电源模式, FF 外部电源模式(20130120增)
//{
// Reset_18b20(); //复位DS18B20
// Write_18b20(SkipRom); //写"跳过ROM"指令,只能用于单器件
// Write_18b20(ReadPower); //写"读电源"指令
// return Read_18b20(); //读取1个字节,并返回
//}

void GetB20SN(uchar *buf_p,uchar start_loca) //获取DS18B20系列号函数,*buf_p指向存储数组,start_loca为存储的起始位置
{
uchar i=8;
buf_p+=start_loca; //指向数组中的存储起始位置
Reset_18b20(); //复位DS18B20
Write_18b20(ReadRom); //写"读存储器"指令
while(i--) *buf_p++=Read_18b20(); //读8个字节系列号
}

/******************************************************************************/
/***函数名称:ChangeTempValue(转换温度值) ***/
/***功能描述:将读取18B20所得的16位温度值(temp_buf指向的2个连续字节), ***/
/*** 转换成1Byte整数部分,和2Byte小数部分,存于save_buf指向的3个连续字节, ***/
/*** 其中第1个字节为整数部分,第2字节为0.01小数部分,第3字节为0.0001小数部分 ***/
/*** 返回值:0温度为正值,1温度为负值 ***/
/******************************************************************************/
bit ChangeTempValue(uchar *temp_buf,uchar reso_bit,uchar *save_buf,uchar save_start) //返回:0正温度,1负温度
{
// 9bit(SSSS SSSS DDDD DDDD): S符号位:0正1负,D数据位,0.5℃单位(/2)
//10bit(SSSS SSSD DDDD DDDD): S符号位:0正1负,D数据位,0.25℃单位(/4)
//11bit(SSSS SSDD DDDD DDDD): S符号位:0正1负,D数据位,0.125℃单位(/8)
//12bit(SSSS SDDD DDDD DDDD): S符号位:0正1负,D数据位,0.0625℃单位(/16)
bit polar=0; //温度极性:0正温度,1负温度
uchar temp_int,reso_value;
uint temp_dec,temp_A;
reso_value=(reso_bit>>5)+9; //分辨率指令码转换数值:Reso_9bit/10bit/11bit/12bit→9/10/11/12
if(reso_value>12) reso_value=12; //默认 12bit分辨率精度
if(*(temp_buf+1)>>3)//正负值识别,温度值高5位为1则为 负值
{
polar=1; //负极性
temp_A=(~*(temp_buf+1)<<8 | ~*temp_buf)+1; //取 补码(取反+1)
}
else temp_A=*(temp_buf+1)<<8 | *temp_buf; //正值,合成16位数据
temp_int=(uchar)(temp_A>>(reso_value-8)); //取整数部分,8bit(可以不加强制转换(uchar))
temp_dec=temp_A & (0x0f>>(12-reso_value)); //取小数部分
switch(reso_bit) //小数转换需进行精度选择
{
case Reso_9bit: //9位精度,0.5℃
temp_dec*=5000; //小数扩大10000倍
break;
case Reso_10bit: //10位精度,0.25℃
temp_dec*=2500; //小数扩大10000倍
break;
case Reso_11bit: //11位精度,0.125℃
temp_dec*=1250; //小数扩大10000倍
break;
case Reso_12bit: //12位精度,0.0625℃
default: //其他精度,按12位精度算
temp_dec*=625; //小数扩大10000倍
break;
}
save_buf+=save_start; //指向存储数组中的存储起始位置
*save_buf++=temp_int; //存温度值整数部分
*save_buf++=temp_dec/100; //存温度值小数点 十分位、百分位
*save_buf=temp_dec%100; //存温度值小数点 千分位、万分位
return polar; //返回温度极性:0正温度,1负温度
}
bit GetTemp(uchar rom_mode,uchar *sn_p,uchar reso_bit,uchar *get_buf,uchar start_loca) //返回:0正温度,1负温度
{
uchar i,read_buf[9]; //定义数组以存储DS18B20的9字节温度结果
uchar read_count=8; //读次数
Reset_18b20(); //复位 DS18B20
Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom
if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*sn_p++); //若ROM操作 为匹配Rom,则写入8字节系列号
Write_18b20(TempChange); //写入"温度转换"指令
sn_p-=8; //指向"系列号起始地址"
do //读暂存器 操作
{
Reset_18b20(); //复位 DS18B20
Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom
if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*sn_p++); //若ROM操作 为匹配Rom,则写入8字节系列号
Write_18b20(ReadScr); //写入"读暂存器"指令
for(i=0;i<9;i++) read_buf[i]=Read_18b20(); //读取暂存器9字节数据
sn_p-=8; //指向"系列号起始地址"
}while(CRC_18b20(read_buf,9) && --read_count); //若校验失败,则重新"读暂存器",Z多读read_count次
return ChangeTempValue(read_buf,reso_bit,get_buf,start_loca); //进行温度转换,将温度结果存于get_buf指向的数组,并返回温度极性:0正温度,1负温度
}
void Config_18b20(uchar rom_mode,uchar *sn_buf,uchar sn_start,uchar up_limit,uchar low_limit,uchar reso_bit) //DS18B20配置函数
{ //形参:rom_mode操作ROM(SkipRom,MatchRom),up_limit上限,low_limit下限,reso_bit分辨率(Reso_9bit/10bit/11bit/12bit)
uchar i,read_buf[9]; //定义数组以存储DS18B20的8字节系列号与1字节CRC校验码
uchar read_count=8; //读次数
sn_buf+=sn_start; //指向 系列号起始地址
do //写暂存器 操作
{
Reset_18b20(); //复位 DS18B20
Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom
if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*(sn_buf+i)); //若ROM操作 为匹配Rom,则写入8字节系列号
Write_18b20(WriteScr); //写暂存器 指令
Write_18b20(up_limit); //写入报警上限温度
Write_18b20(low_limit); //写入报警下限温度
Write_18b20(reso_bit); //写入分辨率
do //读暂存器 操作
{
Reset_18b20(); //复位 DS18B20
Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom
if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*(sn_buf+i)); //若ROM操作 为匹配Rom,则写入8字节系列号
Write_18b20(ReadScr); //写入"读暂存器"指令
for(i=0;i<9;i++) read_buf[i]=Read_18b20(); //读取暂存器9个字节数据
}while(CRC_18b20(read_buf,9) && --read_count); //若校验失败,则重新"读暂存器",Z多读read_count次
}while(read_buf[2]!=up_limit || read_buf[3]!=low_limit); //若读取结果与写入数据不同,则重新 写暂存器

Reset_18b20(); //复位 DS18B20
Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom
if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*(sn_buf+i)); //若ROM操作 为匹配Rom,则写入8字节系列号
Write_18b20(CopyScr); //"复制暂存器"指令,将暂存器内容复制到DS18B20 EEPROM

Reset_18b20(); //复位 DS18B20
Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom
if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*(sn_buf+i)); //若ROM操作为匹配Rom,则写入8字节系列号
Write_18b20(RecallEE); //调EEPROM数据 指令,将 DS18B20 EEPROM内的数据写到暂存器
}

/*
uint GetTempData(uchar rom_mode,uchar *sn_p) //返回:16位 温度结果
{
uchar i,read_buf[9]; //定义数组以存储DS18B20的9字节温度结果
uchar read_count=8; //读次数
Reset_18b20(); //复位 DS18B20
Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom
if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*sn_p++); //若ROM操作 为匹配Rom,则写入8字节系列号
Write_18b20(TempChange); //写入"温度转换"指令
sn_p-=8; //指向"系列号起始地址"
do //读暂存器 操作
{
Reset_18b20(); //复位 DS18B20
Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom
if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*sn_p++); //若ROM操作 为匹配Rom,则写入8字节系列号
Write_18b20(ReadScr); //写入"读暂存器"指令
for(i=0;i<9;i++) read_buf[i]=Read_18b20(); //读取暂存器9字节数据
sn_p-=8; //指向"系列号起始地址"
}while(CRC_18b20(read_buf,9) && --read_count); //若校验失败,则重新"读暂存器",Z多读read_count次
return ((read_buf[1]<<8)|read_buf[0]); //进行温度转换,将温度结果存于get_buf指向的数组,并返回温度极性:0正温度,1负温度
}*/
7 0 2016-06-14 0条评论 回复
您可能感兴趣的社区主题
加载中...
发布 评论