跪求指点DS18B20程序 一个温控系统的温度传感器部分 结构如下:

2024-12-27 18:52:56
推荐回答(2个)
回答1:

这是我之前写的一个程序 希望能帮到你 有问题可以探讨下
#include
#include
#define data P0
#define uchar unsigned char
#define uint unsigned int
uchar TEMP;// 温度值的变量;
uchar flag1;
sbit RS=P2^0;
sbit RW=P2^1;
sbit LCDE=P2^2;
sbit DQ=P2^3;
sbit bflag=ACC^7;
uchar tab1[]={'0','1','2','3','4','5','6','7','8','9'};
uchar idata tab2[2][16]={{"Be careful "},{"temperature: "}};
uchar buf[2];
void delay1(uchar i)
{
while(--i);
}
void delay3 (unsigned int count)
{
unsigned int i;
while (count)
{
i =200;
while (i>0) i--;
count--;
}
}

void tmreset (void)// 发送复位和初始化
{
unsigned int i;
DQ = 0;
i = 103;
while (i>0) i--; // 延时
DQ = 1;
i = 4;
while (i>0) i--;
}

bit tmpread (void)// 读取数据的一位
{
unsigned int i;
bit dat;
DQ = 0; i++;
DQ = 1; i++; i++;//延时
dat =DQ;
i = 8; while (i>0) i--;// 延时
return (dat);
}

unsigned char tmpread2 (void)//读一个字节
{
unsigned char i,j,dat;
dat = 0;
for (i=1;i<=8;i++)
{
j = tmpread ();
dat = (j << 7) | (dat >> 1);
}
return (dat);
}

void tmpwrite (unsigned char dat)//写一个字节
{
unsigned int i;
unsigned char j;
bit testb;
for (j=1;j<=8;j++)
{
testb = dat & 0x01;
dat = dat >> 1;
if (testb)
{
DQ = 0;// 写0
i++; i++;
DQ = 1;
i = 8; while (i>0) i--;
}
else
{
DQ = 0;// 写0
i = 8; while (i>0) i--;
DQ = 1;
i++; i++;
}
}
}

void tmpchange(void)// ds1820 开始转换
{
tmreset ();// 复位
//tmpre ();// 等待存在脉冲
delay3 (1);// 延时
tmpwrite (0xcc);// 跳过序列号命令
tmpwrite (0x44);// 发转换命令 44H,
}

uchar tmp (void)// 读取温度
{
unsigned int a,b,t;
tmreset ();// 复位
delay3 (1);// 延时
tmpwrite (0xcc);// 跳过序列号命令
tmpwrite (0xbe);
a=tmpread2();
b=tmpread2();// 发送读取命令
b<<=4;
b+=(a&0xf0)>>4;
t=b;
return(t);
/*buf[0] = tmpread2 ();// 读取低位温度
buf[1] = tmpread2 (); //读取高位温度
flag1=buf[1]&0xf8;//若b为1则为负温
if(flag1)
{
buf[0]=~buf[0];
buf[1]=~buf[1];//如果为负温则去除其补码
}
buf[0]=(buf[0]>>4);
buf[0]=(buf[0]&0x0f);
buf[1]=buf[1]<<4;
buf[1]=buf[1]&0xf0;
TEMP=(buf[0]|buf[1]);
if(flag1)
{
TEMP++;
}
buf[0]=TEMP%10;
buf[1]=TEMP/10;*/
}
rom()// 读取器件序列号子程序
{
tmreset ();//复位
delay3 (1);//延时
tmpwrite(0x33);//发送读序列号子程序

}
busy_check() //忙检查询
{
register uchar lcd_start;
RS=0;
RW=1;
LCDE=1;
delay1(30);
lcd_start=data;
LCDE=0;
return(lcd_start&0x80);
}
wr_com(uchar comm) //写控制字命令
{
while(busy_check());
RS=0;
RW=0;
LCDE=1;

data=comm;
LCDE=0;
}
wr_dat(uchar dat) //写字符到LCD
{
while(busy_check());
RS=1;
RW=0;
LCDE=1;

data=dat;
LCDE=0;
}

void init()//led 初始化
{
wr_com(0x38); //设置显示模式:8位子行5×7点阵
wr_com(0x80); //关闭显示屏
wr_com(0x0c); //显示器开、光标开、光标允许闪烁
wr_com(0x06); //文字不动,光标自动右移
wr_com(0x01);//清屏光标复位
}
void display1()//温度显示函数
{
uchar j,k;
wr_com(0x80);
for(j=0;j<16;j++)
{
wr_dat(tab2[0][j]);
}
wr_com(0xc0);
for(k=0;k<16;k++)
{
wr_dat(tab2[1][k]);
}

}
void main()
{uchar temp;
delay1(10);
init();
while(1)
{
tmpchange();// 开始温度转
temp=tmp();
tab2[1][14]=tab1[temp/10];//读取温度
tab2[1][15]=tab1[temp%10];
/*tab2[1][14]=tab1[buf[1]];
tab2[1][15]=tab1[buf[0]]; */
display1();
}
}

回答2:

#ifndef __18B20_H__
#define __18B20_H__
#include
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2; //数据线
uchar Decimals=0; //小数部分
void Delay(uchar t)
{
while(--t);
}
/******************************************
此延时函数针对的是12Mhz的晶振
delay(0):延时518us 误差:518-2*256=6
delay(1):延时7us (原帖写"5us"是错的)
delay(10):延时25us 误差:25-20=5
delay(20):延时45us 误差:45-40=5
delay(100):延时205us 误差:205-200=5
delay(200):延时405us 误差:405-400=5
*******************************************/
void delay_ms(uint t)
{
uint i,j;
for(i=0;i for(j=0;j<125;j++);
}
/**********************************************************
函数功能:DS18B20初始化函数
入口函数:无
出口函数:无
**********************************************************/
void DS18B20_Init(void)
{
bit n;
DS=1;
Delay(1);
DS=0;
Delay(250); // 480~960us
DS=1;
Delay(20); // 15~60us
n=DS;
Delay(100); // 60~240us
DS=1;
Delay(1);
}
/**********************************************************
函数功能:DS18B20写一个字节
入口函数:dat--要写的数据
出口函数:无
**********************************************************/
void Write_Byte(uchar dat)
{
uchar i=0;
for(i=0;i<8;i++)
{
DS=0;
DS=dat & 0x01;
Delay(10);
DS=1;
dat>>=1;
}
Delay(4);
}
/**********************************************************
函数功能:DS18B20读一个字节
入口函数:无
出口函数:value--读取的数据
**********************************************************/
uchar Read_Byte(void)
{
uchar i,value;
for(i=0;i<8;i++)
{
DS=0;
value>>=1;
DS=1;
if(DS)
value|=0x80;
Delay(10);
}
return value;
}
/**********************************************************
函数功能:读取18B20内的温度
入口函数:无
出口函数:temper--温度的整数部分, Decimals--小数部分
**********************************************************/
uchar Read_Temper(void) //读取温度
{
static bit flag=0;
uchar a,b,temper;
DS18B20_Init();
Write_Byte(0xcc); //跳过匹配ROM
Write_Byte(0x44); //开始转换温度
if(flag==0) //第一次温度转化需要给它足够的时间
{
delay_ms(1000); //温度转换需要时间 93.75ms
flag=1;
}
DS18B20_Init();
Write_Byte(0xcc); //跳过匹配ROM
Write_Byte(0xbe); //读取暂存器中的内容
a=Read_Byte(); //读取高八位
b=Read_Byte(); //读取低八位
temper=b;
temper<<=4;
temper+=(a & 0xf0)>>4;
Decimals=(a&0x0f)*0.0625*100; //小数部分
return temper;
}
#endif