[51单片机]

DS18B20显示温度

[复制链接]
1119|7
手机看帖
扫描二维码
随时随地手机跟帖
蔬木果|  楼主 | 2017-12-20 21:41 | 显示全部楼层 |阅读模式
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int  
sbit BEEP=P2^1;   
//sbit led=P1^0;
//sbit led0=P1^1;
//sbit led1=P1^2;
sbit s0=P1^4;
sbit s1=P1^5;
sbit s2=P1^6;  
uchar code tab_0[]="Temp:           ";
uchar code tab_1[]="TH:23    TL:18  ";
uchar TH,TL;                  // 定义高低温度变量
uchar num;                    //全局变量  
/********ms延时(非精确)**********/
void delay(uint z)   
{  uint i,j;
for(i=z;i>0;i--)  
for(j=120;j>0;j--);
}  
/*******TH、TL的温度符号**********/
//void   fuhao()
//void  write_com()
//void  write_dat()

// {  
// write_com(0x80+5);
// write_dat(0xdf);
  //write_dat(0x43);
// write_com(0x80+14);
// write_dat(0xdf);
// write_dat(0x43);
//}
/*************初始化**************/
void init() {  
/***********上电显示初始化**********/
uchar i;
TH=23;TL=18;
write_com(0x80);
for(i=0;i<16;i++)  
{   
write_dat(tab_1[i]);   
delay(5);
}  

write_com(0x80+0x40);
  for(i=0;i<5;i++)  
  {  
   write_dat(tab_0[i]);  
   delay(5);
  }
//fuhao();  

/********定时器初始化*************/  
TMOD=0x01;        //开定时器T0,方式1   
TH0=(65536-50000)/256;   //装入初值
TL0=(65536-50000)%256;   //   
EA=1;     //开全局中断
ET0=1;     
TR0=1;    //打开定时器  
}  
/**********报警函数**************/
void bi(uint t)
{  int i,j;
    for(i=0;i<t;i++)
   {  
    for(j=0;j<50;j++);
    BEEP=~BEEP;      //按位取反BEEP
         }
}

/*******TH、TL取十位个位送人显示***********/
void writeT_HL(uchar add,uchar dat)
{  uchar shi,ge;
   shi=dat/10;    //十位
   ge=dat%10;     //个位
write_com(0x80+add);
write_dat(shi+0x30);  
write_dat(ge+0x30);  
}
/*******按键函数********/
void keyscan() {

/**********功能选择**********/  
if(s0==0)  
  {  num++;   
    delay(2);  
  if(s0==0)  
{    //  led=0;
   while(!s0);
   {bi(300);
//led=1;
}
//按一下灯亮一下声音响一声  

if(num==1)
{TR0=0;
write_com(0x80+12);
delay(10);
}
//
write_com(0x0f);  
if(num==2)
{write_com(0x80+4);}     
if(num==3)
{num=0;
  TR0=1;
}
}
}
/*********功能加*********/      
  if(num!=0)
  {   
  if(s1==0)  
   {   
    delay(2);  
    if(s1==0)
{      
//led0=0;  
while(!s1);
{bi(300);
// led0=1;
} //按一下灯亮一下声音响一声  
if(num==1)
{TH++;
if(TH==100)
  TH=0;
writeT_HL(3,TH);
write_com(0x80+4);}  

if(num==2)
{TL++;
if(TL==100)
TL=0;
writeT_HL(12,TL);
write_com(0x80+10);}      

}

}  
}  
/**********功能减************/   
if(num!=0)   
{   if(s2==0)   
  {     delay(2);  
    if(s2==0)   
          {     // led1=0;  
while(!s2);
{bi(300);
//led1=1;
} //按一下灯亮一下声音响一声  
if(num==1)
{TH--;
if(TH==-1)
TH=99;
writeT_HL(3,TH);
write_com(0x80+4);}
    if(num==2)
{TL--;
if(TL==-1)
TL=99;
writeT_HL(12,TL);
write_com(0x80+10);}      

}
}  
}   
}
/*****温度报警函数*******/
void baojing()
{
uchar temp;
temp=temp/10;   //返回的温度值temp放大了十倍,得除十还原
if(TH<=temp)
  { bi(500);}
  if(TL>=temp)
   { bi(500);}
}
/***************主函数***************/  
void main(void) {  
Init_1602();
  init();
   while(1)  
    { BEEP=0;   
  keyscan();   
ds1820disp();  
baojing();  
}
}


/***********定时器中断函数************/
void time() interrupt 1 {
TH0=(65536-50000)/256;  //重装初值
TL0=(65536-50000)%256;  
}
//DS1802驱动程序
#ifndef __DS18B20_H__
#define __DS18B20_H__  
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P2^7;
uchar tab[5];
uint temp;    //温度值
bit tflag;  
/**************** 延时1微秒**********/  
void delay_18B20(uint i)
  {   while(i--); }
/******************* ds1820复位************/
void ds1820rst()
{    uchar x=0;

DQ=1;              //DQ复位
delay_18B20(8);    //延时
  DQ=0;              //DQ拉低

delay_18B20(80);   //精确延时大于480us
DQ=1;              //拉高
delay_18B20(14);

x=DQ;              //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
while(!DQ);
  delay_18B20(20);
}
/******************** 读一个字节********************/  
uchar ds1820rd()
  {  
   uchar i=0;
   uchar dat=0;
     for (i=8;i>0;i--)
          {   
            DQ=0;     //给脉冲信号
            dat>>=1;
        DQ=1;     //给脉冲信号  
  if(DQ)
    dat|=0x80;
    delay_18B20(4);
         }
return(dat);
}
/*************** 写一个字节***************/
void ds1820wr(uchar dat)
{  uchar i=0;
  for (i=8;i>0;i--)
   {    DQ=0;
     DQ=dat&0x01;
           delay_18B20(5);
              DQ=1;   
                  dat>>=1;
}
}
/****************读取温度 值并转换***************/
  read_temp() {  
uchar a,b;   
  ds1820rst();     
    ds1820wr(0xcc);//跳过读序列号   
         ds1820wr(0x44);//启动温度转换  

delay_18B20(100);
    ds1820rst();     
    ds1820wr(0xcc);//跳过读序列号   
         ds1820wr(0xbe);//读取温度   

delay_18B20(100);
    a=ds1820rd();   
          b=ds1820rd();   
           temp=b;   
            temp<<=8;   
                  temp=temp|a;
if(temp<0x0fff)

tflag=0;
  else  
{  temp=~temp+1;  
tflag=1;
}
temp=temp*(0.625);//温度值扩大10倍,精确到1位小数
return(temp);
}
/***************** 温度值显示****************/
void ds1820disp()
{   
uchar flagdat;
read_temp();
tab[0]=temp%1000/100+0x30;         //十位数  
tab[1]=temp%100/10+0x30;           //个位数  
tab[2]=temp%10+0x30;               //小数位  
if(tflag==0)

flagdat=0x20;//正温度不显示符号
    else   
          flagdat=0x2d;//负温度显示负号:-     

if(tab[0]==0x30) { tab[0]=0x20; }//如果十位为0,不显示  
write_com(0x80+0x40+6)
write_dat(flagdat);    //显示正负
write_dat(tab[0]);    //显示十位
write_dat(tab[1]);    //显示个位  
write_dat(0x2e);          //显示小数点  
write_dat(tab[2]);    //显示小数位
write_dat(0xdf);  write_dat(0x43);
}
#endif
// LCD1602驱动程序
#ifndef __1602_H__
#define __1602_H__  
#define uint unsigned int
#define uchar unsigned char
#define LCD P0
sbit RS=P3^0;
sbit RW=P3^1;
sbit EN=P3^2;
void delayms(uint z);
void Init_1602(void);
void check_busy(void);
void write_com(uchar com);
void write_dat(uchar dat);  
/********************延时z毫秒****************/  
void delayms(uint z)
{
int i,j;
for(i=z;i>0;i--)   
for(j=120;j>0;j--);
}  
/******************** 1cd1602初始化******************/
void Init_1602(void)
{  delayms(15);  
write_com(0x38);
  delayms(5);
   write_com(0x0c);  
   delayms(5);
    write_com(0x06);
         delayms(5);
          write_com(0x01);
           delayms(5);
            write_com(0x80);  
                delayms(5);
}
/************************** 将数据二进制高地位对换 (为了连线方便但片机P0口 与lcd1602数据口反接) ****************************/ uchar HL_exchange(uchar dat)
{
        uchar i,temp;  
                       temp = 0x00;   
                                 for(i=0;i<8;i++)
{
                temp >>= 1;         
                                        if((dat<<i)&0x80)        
                                                         {
                        temp |= 0x80;                 }
                                                                else                 {
                        temp &= 0x7F;                 }         }
        return temp; }  
/**********读忙*****************/
void  check_busy(void)
{  uchar x;
x=HL_exchange(0x80);
   while(x&HL_exchange(0x80))
    {   RS=0;
          RW=1;   
          EN=1;  
           x=LCD;  
            EN=0;  
                 delayms(10);
}
}  
/**************写指令**************/
void write_com(uchar com)
{  check_busy();
  RS=0;
   RW=0;
    EN=1;
         LCD=0XFF;
LCD=HL_exchange(com);
   EN=0;  delayms(10);
}
/**************写数据**************/
void write_dat(uchar dat)
  {  check_busy();
   RS=1;  
RW=0;  
EN=1;
LCD=0XFF;
LCD=HL_exchange(dat);
  EN=0;
   delayms(10); }
#endif

总是显示8.C(39): warning C206: 'write_com': missing function-prototype
求助怎么修改程序

相关帖子

linqing171| | 2017-12-20 21:47 | 显示全部楼层
include一下你的   有    __1602_H__ 这句的头文件.
比如 #include "1602.h"


或者 把
void write_com(uchar com);
这句复制到c文件的前面部分.

使用特权

评论回复
ningling_21| | 2017-12-21 10:43 | 显示全部楼层
函数需要先定义(声明)后调用

使用特权

评论回复
cactus0117| | 2017-12-21 14:58 | 显示全部楼层

使用特权

评论回复
蔬木果|  楼主 | 2017-12-22 00:00 | 显示全部楼层
ningling_21 发表于 2017-12-21 10:43
函数需要先定义(声明)后调用

恩恩,明白了。

使用特权

评论回复
蔬木果|  楼主 | 2017-12-22 00:01 | 显示全部楼层
linqing171 发表于 2017-12-20 21:47
include一下你的   有    __1602_H__ 这句的头文件.
比如 #include "1602.h"

恩恩,清楚了。

使用特权

评论回复
zqx1000| | 2018-4-10 22:34 | 显示全部楼层
kankan

使用特权

评论回复
sum123456| | 2018-4-11 07:11 | 显示全部楼层

程序小白。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

171

帖子

2

粉丝