我给你发一个现成的供参考,满足前3条。后两条附加功能十分容易,你自己加上吧,那很容易的。如果看不懂,再与我联系。楼上哥哥姐姐说得很对,还是要靠自己真正掌握才行,又不难。
已经发到你的邮箱了。收到回一个。
//========================================================
// 文件名称: DS18B20.c
// 功能描述: DS18B20的相关操作,通过用户接口函数取得函数值
// 维护记录: 2008-12-07 v1.0
//========================================================
#include
#include
//========================================================
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
#define NOP _nop_()
#define ALARM P3_2
#define D_STB P0_7 // 串行显示,STB是使能端,高电平有效
#define DQ P1_7 // DS18B20 数据口接在 P1.7 上
#define Init_Dy300uS 100 // DS18B20初始化等待值
//#define Wait _nop_()
#define TRUE 1
#define FALSE 0
#define V_TH1 0X3C /* T1定时50毫秒初值,应为3CB0H,考虑误差,加AH */
#define V_TL1 0XBA
#define V_1ms 123 /* 1毫秒定时初值 */
#define V_10ms 1631 /* 10毫秒定时初值 */
#define V_100ms 16585 /* 100毫秒定时初值 */
#define V_1s 8 /* 1秒定时初值 */
#define P10 P1_0
#define P11 P1_1
#define P12 P1_2
#define P13 P1_3
#define P14 P1_4
#define P15 P1_5
#define P16 P1_6
#define P17 P1_7
uchar code Wel[] = {"Welcome!"};
uchar code Te[] = {"Temp:"};
static uchar V_Time; /* 静态变量,存储T1 定时器中断次数,最大 20 */
//static ulong V_Count; /* 静态变量,存储T0 计数值,最大 9999 9999 */
static uchar V_Ic; /* T0中断次数计数器,每次中断代表计数10000 */
static bit Dis_En;
static uchar V_Data; /* 键值 */
//static unsigned char Tep_Temp; // 存放温度的采集值
static uint Temp_Data; // 温度转换的结果
//static uchar Temp_DataL;
//static uint Temp_DataL; // 低位
static uchar Key_Dw;
sbit ACC_0 = 0XE0;
sbit ACC_7 = 0xE7;
//static unsigned char AD_Data;
static uchar AD_OK = 0; //AD转换完成,AD_OK = 1
uchar Buf[6];
//////////////////////////////////////////////////////////
void Init(void)
{
IP=8; /*T1中断优先级最高*/
IE=0; /*禁止中断*/
TMOD=0x15; /*设置 T1--16位定时器,T0--十六位计数器*/
PCON=0; /*设置 SMOD=0*/
TCON=0; //SET EDGE TRIGGER
SCON=0; /*0000 0000B,串行方式0,禁止接收*/
P3=0xFF; /*1111 1111B */
P3_7 = 0; /* 关报警 */
P0=0xFF; // 1111 1111
PSW=0;
EA=0; //CPU INTERRUPTION ALLOW
ACC=0;
}
///////////////////////////////////////////////////////////
//========================================================
void Lcd_wc(int cmd) ;
void Lcd_wd(unsigned char dat);
void Lcd_init(void);
void Lcd_str( uchar *p, uchar flag );
//========================================================
//////////////////////////////////////////////////////////////
void Delay(unsigned int uiTime);
unsigned int Read_DQ(void);
//////////////////////////////////////////////////////////////
void Dy15uS(void)
{
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
}
//////////////////////////////////////////////////////////////
void Dy30uS(void)
{
Dy15uS();
Dy15uS();
}
//////////////////////////////////////////////////////////////
void Dy60uS(void)
{
Dy15uS();
Dy15uS();
Dy15uS();
Dy15uS();
}
//////////////////////////////////////////////////////////////
void Dy1mS(void)
{
uint i=0;
for (i=0;i<=V_1ms;i++)
;
_nop_();
}
//======///////////////////////////////////////////////////////
void Dy10mS(void)
{
uint i=0;
for (i=0;i<=V_10ms;i++)
_nop_();
_nop_();
}
//===============================================================
void Dy100mS(void)
{
uint i=0;
for (i=0;i<=V_100ms;i++)
{
_nop_();
}
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
//=================================================================================
void Dy500mS(void)
{
Dy100mS();
Dy100mS();
Dy100mS();
Dy100mS();
Dy100mS();
}
//========================================================
// 语法格式: unsigned int Read_18B20_Byte(void)
// 实现功能: 读取18B20的值
// 参数: 无
// 返回值: 18B20的值
//========================================================
unsigned char Read_18B20_Byte(void)
{
char i;
// unsigned char Data;
ACC = 0;
for(i=0;i<8;i++)
{
DQ = 1; // 两次采样间隔>1uS,取延时2uS
NOP;
NOP;
DQ = 0;
NOP;
NOP; // 低电平维持2uS
DQ = 1; // 切为输入
Dy15uS();
ACC>>=1;
ACC_7 = DQ;
Dy60uS(); // 读完后1位后,延时60uS
}
DQ = 1;
return(ACC);
}
//========================================================
// 语法格式: void Write_18B20_Byte(unsigned char Data)
// 实现功能: 写18B20 一个字节,8bit
// 参数: 要写的字节
// 返回值: 无
//========================================================
void Write_18B20_Byte(unsigned char Data)
{
char i;
DQ = 1;
Delay(1);
for(i=0;i<8;i++)
{
DQ = 0; // DQ=0 后的15~60uS间,18B20对DQ采样
NOP; // 延时 5 uS
NOP;
NOP;
NOP;
NOP;
if((Data&0x0001)>0)
DQ = 1;
Data = Data >> 1;
Delay(6); // 延时60uS
DQ = 1;
NOP;
NOP;
NOP;
}
DQ = 1;
}
//========================================================
// 语法格式: char Init_18B20(void)
// 实现功能: 初始化18B20
// 参数: 无
// 返回值: flag = 0 18B20存在 ;flag = 1 没有检测到18B20
//========================================================
char Init_18B20(void)
{
uchar flag,DDD;
DQ = 1; // 初始化,DQ先置高电平
NOP;
NOP;
DQ = 0; // 维持低电平500uS
Delay(45); // 延时500uS
DQ = 1;
/*
如果DS18B20存在,
DS18B20 检测到DQ低电平变高15~60uS后,发出低电平信号,
维持60~240uS,共300uS 。
*/
DDD = Init_Dy300uS; // 本过程共300uS
while ( DDD > 0 ) // 检测DS18B20是否存在
{
if( !DQ ) // 检测到DQ = 0 ;DS18B20存在,返回 0
{
flag = 0;
DQ = 1;
while(!DQ) // 等待DQ释放,恢复高电平
;
return (flag); // 检测到18B20,返回flag = 0 ;
}
DDD -=1 ; // 在300uS内检测不到DQ低电平,失败。
}
flag = 1; // 没有检测到,返回flag = 1
return(flag);
}
//========================================================
// 语法格式: void Delay(unsigned int TTT)
// 实现功能: 延时,在调用Delay(1)时,延时时间小于1us
// 参数: uiTime
// 返回值: 无
//========================================================
void Delay(unsigned int TTT)
{
while(TTT > 0)
{
TTT -= 1;
}
}
//========================================================
// 语法格式: unsigned int Read_DQ(void)
// 实现功能: 读取DQ的值
// 参数: 无
// 返回值: DQ的值
//========================================================
/*
unsigned char Read_DQ(void)
{
unsigned char Temp;
Temp = 0;
if(DQ)
Temp = 1;
return(Temp);
}
*/
//========================================================
// 语法格式: unsigned int Read_Temp(void)
// 实现功能: 读取温度
// 参数: 无
// 返回值: 温度值
//========================================================
void Read_Temp(void)
{
char i;
unsigned char Temp_DataH; // 暂存温度数据
unsigned char Temp_DataL;
DQ = 1;
while(Init_18B20()>0) // 检测DS18B20是否存在,等于0,存在。
Delay(44); // 不等于零,延时500uS后,继续测试
Write_18B20_Byte(0xcc); // 访问一次18B20的ROM
NOP;
Write_18B20_Byte(0x44); // 启动温度变换
for(i=0;i<=5;i++)
Dy100mS(); // 长时间延时,500mS
while(Init_18B20()>0)
;
Write_18B20_Byte(0xcc); //允许总线控制器不用提供64 位ROM
//编码就使用存储器操作命令
Write_18B20_Byte(0xbe); // Read Scratchpad(读暂存存储器)
Temp_DataL = Read_18B20_Byte(); //数据读取,读暂存区2个字节
Temp_DataH = Read_18B20_Byte();
Temp_Data = Temp_DataH;
Temp_Data <<=8;
Temp_Data += Temp_DataL;
Init_18B20();
}
//=======================================================================================
void Htod(unsigned int Temp_Data); // 数据处理函数声明
//=======================================================================================
/*
void Display(void)
送显示子程序,将Temp_Data中的长整形数转换成十进制数,
查表产生显示段码,删除有效数字前面的0,加上小数点,
送LCD1602显示
*/
void Display(void)
{
// bit Dis0; // 高位是0的标志位
// Lcd_clr();
Htod(Temp_Data); // 将温度的补码转换成ASCII码
Lcd_wc(0xc8); // 显示位置
Lcd_wd(Buf[6]); // 先送符号位
// Dis0=0;
D_STB = 0;
/* 消除整数有效数字前面的0,送暗 */
if (Buf[5] == 0x30)
Lcd_wd(' ');
else
Lcd_wd(Buf[5]);
if ((Buf[4] == 0x30)&(Buf[5] == 0x30))
Lcd_wd(' ');
else
Lcd_wd(Buf[4]);
Lcd_wd(Buf[3]);
Lcd_wd('.');
Lcd_wd(Buf[2]);
Lcd_wd(Buf[1]);
Lcd_wd(Buf[0]);
D_STB = 1;
}
//================================================================================
void TT1(void) interrupt 3 /* T1 50毫秒定时器中断服务程序 */
{
TR1=0; /* 重装T1 定时初值 */
TL1=V_TL1;
TH1=V_TH1;
TR1=1;
V_Time++;
if (V_Time==20)
{
EA = 0;
TR1 = 0;
TR0 = 0;
TF1 = 0;
TF0 = 0;
Dis_En=1; /* 显示标志置位 */
}
}
//===================================================================================
int main(void)
{
uint Temp_Disp = 0;
uchar *P;
Init();
EA = 1;
TR1 = 1;
TR0 = 1;
TF1 = 1;
TF0 = 1;
Dis_En = 1; /* 显示标志置位 */
Init_18B20();
Lcd_init();
P = Wel; // 显示"Welcome!"
Lcd_str(P,1);
P = Te; // 显示"Temp:"
Lcd_str(P,2);
Dis_En = 1;
while (Dis_En == 1)
{
Read_Temp();
if (Temp_Disp!=Temp_Data)
{
Temp_Disp = Temp_Data; // 数据更新才刷新显示
Display();
}
EA = 1;
TR1 = 1;
TR0 = 1;
TF1 = 1;
TF0 = 1;
// Dis_En = 0; /* 显示标志置位 */
}
}
//========================================================
// 数据处理 Htod(unsigned int Temp_Data)
// 语法格式:unsigned int Read_18B20_Byte(void)
// 实现功能:将读出的DS18B20数据先求补,然后转换成BCD码
// 如果送液晶显示,应转换成ASCII码
// 参数:要转换的数,共2字节,整数部分7位二进制数,小数部分
// 4位二进制数
// 转换方法:乘权相加
// 返回值:
//========================================================
void Htod(unsigned int Temp_Data)
{
// unsigned int Data[10] = {0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039};
unsigned int Fuhao; // 符号
unsigned int Integer; //数据的整数部分
unsigned int Decimal; //数据的小数部分
// unsigned int Shi; //显示温度的十位
// unsigned int Ge; //显示温度的个位
// unsigned int Shi_d; //显示温度的十分位
// unsigned int Bai_d; //显示温度的百分位
// unsigned int Qian_d; //显示温度的千分位
unsigned int Residue; //数据的余数,作除法
Integer = 0;
Decimal = 0;
// 求补码
Fuhao = 0;
Fuhao = Temp_Data;
Fuhao = (Fuhao & 0xf000) ; // 只保留符号位
if ( Fuhao > 0 ) // Fuhao>0 是负数
Fuhao = 0xffff;
else
Fuhao = 0;
Temp_Data ^= Fuhao; // 负数求反加1
if ( Fuhao>0 )
Temp_Data += 1;
// if((Temp_Data & 0x7ff) > )
// Temp_Data = 127; // 测温上限是127
// 数据处理
// 处理整数部分
if(Temp_Data & 0x0800) // D10的权是64
Integer += 128;
if(Temp_Data & 0x0400) // D10的权是64
Integer += 64;
if(Temp_Data & 0x0200) // D9的权是32
Integer += 32;
if(Temp_Data & 0x0100) // D8
Integer += 16;
if(Temp_Data & 0x0080) // D7
Integer += 8;
if(Temp_Data & 0x0040) // D6
Integer += 4;
if(Temp_Data & 0x0020) // D5
Integer += 2;
if(Temp_Data & 0x0010) // D4
Integer += 1;
// 处理小数部分
if(Temp_Data & 0x0008) //D3的权是0.5
Decimal += 5000;
if(Temp_Data & 0x0004) // D2的权是0.25
Decimal += 2500;
if(Temp_Data & 0x0002) // D1的权是0.125
Decimal += 1250;
if(Temp_Data & 0x0001) // D0的权是0.0625
Decimal += 625;
// 处理正负号
if(Fuhao>0) // 负数符号显示'-'
Buf[6] = 0XB0; // '-'的ASCII字符
else
Buf[6] = '+'; // '+'的ASCII字符
// 处理整数部分,最大为128,化为单字节BCD码,并+0X30变为ASCII码
Buf[5] = Integer/100+0X30; //整数部分共有3位
Residue = Integer%100;
Integer = Residue;
Buf[4] = Integer/10+0X30;
Residue = Integer%10;
Buf[3] = Residue+0x30;
Buf[2] = Decimal/1000+0X30; //小数点后面部分
Residue = Decimal%1000;
Decimal = Residue;
Buf[1] = Decimal/100+0X30;
Residue = Decimal%100;
Decimal = Residue;
Buf[0] = Decimal/10+0X30;
Residue = Decimal%10; //万分位
这里不会有人帮忙写的,LZ还是老老实实找资料做一个
数字温度计,搜DS18B20 ,上AVR总论坛
这个做出来说容易容易 说难也难 关键是耗时间 不是不愿意帮忙 我建议楼主还是自己查查资料 做个试试 自己能做出来的 爱电子社区