1602液晶显示DS18B20温度

  //LCD1602驱动程序
#include 
#include 
#define uchar unsigned char
#define uint unsigned int
//少占鱼制作  河北正定欢迎您   长沙航空职业技术学院  2010 年QQ:411656434 
#define LCD1602_RS  P2_5 //定义引脚
#define LCD1602_RW  P2_6
#define LCD1602_E   P2_7
#define LCD1602_IO  P0
#define Busy    0x80 //用于检测LCD1602状态字中的Busy标识
const uchar num[]="0123456789.-+";
void WriteData(uchar DAT);
void WriteCommand(uchar command,BuysC);
uchar ReadData(void);
void Readbusy(void);
void LCD1602_Init(void);
void DisplayOneChar(uchar X, uchar Y, uchar DData);
void Displaystring(uchar X, uchar Y, uchar code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
void delayms(uchar);
uchar code a[] = {"WENDUCONGZHI"};
uchar code b[]={"LMT:2"};
uchar code c[]={"MAX:9"};
uchar a0,a1,a2,a3;
uint aa;
float wendu;//得到的十进制温度值       
uchar temp[2]={0,0};  //存放DS18B20的温度寄存器值
uint value = 0;   //读字节变量
sbit FM=P2^2;     //超温 控制 引脚   
sbit DQ=P2^0;       //数据线  
void ReadSerialNumber(void);
void ow_reset(void);
void tmstart (void);
void ReadSerialNumber(void);
void Read_Temperature(void);
void write_byte(char);
uint read_byte(void);
void delay_18B20(uint);
void baojing();
void zhuanhuan();
void delay_led(uint z);

/******转换************/
void zhuanhuan()
{
   aa=wendu;
   
   a1=aa/100; //百位
   a2=aa%100/10; //十位
   a3=aa%10;    //个位 
}

//========18b20延时程序=================*/
void delay_18B20(uint seconds)   //12us延时  
{
     for(;seconds>0;seconds--);
}
/******************************************
          18b20程序
******************************************/
//===============复位 ===========
 void ow_reset(void)
{
    uchar x;
    DQ = 0;          //pull DQ line low
    delay_18B20(88);       //至少480微秒, 
    DQ = 1;         
    delay_18B20(12);     // wait for presence18b20 36us
    x = DQ;   //   X=0,则 初始化成功 ,X=1,则 失败  。       
                     
    delay_18B20(22);   
}
//=========从总线上读取一个字节========
uint read_byte(void)
{
    uchar i;
    for (i=8;i>0;i--)
    {
        value>>=1;   
        DQ = 0;           
        _nop_();_nop_();_nop_();_nop_();
        DQ = 1;               
        if(DQ)
        {
            value|=0x80;   //取出高位数据    
        }
        delay_18B20(8);      
     }
     return(value);  //返回 value值 
}
//===========向18B20写一个字节=================
void write_byte(char val)
{
    uchar i,j;
    for (i=8; i>0; i--)  // writes byte, one bit at a time
    {
        DQ = 0;         // pull DQ low to start timeslot
        j++;            /*延时4us*/
        DQ = val&0x01;   //从低位开始写  
        delay_18B20(12);   
        DQ = 1;
        j++;
        val>>=1;   //写完一位 ,移除它 
     }
}
//============读取温度============
void Read_Temperature(void)
{
   uint k,i,t;
  float  temple;            /*存放读取的温度值 将其除以16即为得到的值*/
    ow_reset();     //复位 
    k++;              //延时4us
 k++;
 k++;
 k++;
    write_byte(0xCC); //直访ROM
    k++;              //延时4us
    write_byte(0xBE); // 写入读命令 
    k++;k++;          //延时8us
    temp[0]=read_byte();     //读取低字节
    temp[1]=read_byte();    //读取高字节
    i=temp[1];
 t=temp[0];
 i=i<<8;
 i=i|t;    
    if((temp[1]&0x80))     //符号位判断
    {
        temple=(~i+1);   //如果为负温则去除其补码 ,先将 补码转换成 原码  
         a0=num[11]; /*表示温度为负数   */    
    }          
    else
    {
        temple=i;
     a0=num[12]; //*表示温度为正数  
    }  
  k=0;
    wendu=temple*0.0625;
 wendu=wendu*10+0.5; 
}
//=======初始化============
void tmstart (void)
{
    ow_reset();    //复位
    delay_18B20(3);      //延时  
    write_byte(0xCC);    //跳过序列号命令,对所有器件有效     
    write_byte(0x44);    //发转换命令 44H,    
}
//========报警===========//
void baojing()
{
 if(aa>=34)
  FM=0;
  else if( aa<=31)
  FM=1;
}

//
void delayms(uchar i)  

    uchar j;
    for(;i>0;i--)
 for(j=0;j<125;j++)
 {;}
}
 void delays(uint m)
{
uint i,j;
for(i=0;i  {
    for(j=0;j<1000;j++)
     {;}
   }
}
//
void main(void)
{
 uchar shuju;
 delayms(2);
 Delay400Ms(); //启动等待,等LCM讲入工作状态
 delays(1);
 LCD1602_Init(); //LCM初始化    
 Delay5Ms(); //延时片刻(可不要)   
 shuju=ReadData();
 Displaystring(2, 0, a);
 tmstart (); //18B20初始化    
    delay_18B20(58);   

  while(1)
  {
    
     Read_Temperature();  //读温度   
        delay_18B20(59);
        tmstart(); //初始化   
        delay_18B20(59);    //*等待转换结束 
  zhuanhuan();   // 显示数值转换  
  DisplayOneChar(0,1,a0);
  DisplayOneChar(1,1,num[a1]);
  DisplayOneChar(2,1,num[a2]);
  DisplayOneChar(3,1,num[10]);
  DisplayOneChar(4,1,num[a3]);
  Displaystring(6,1,b);
  Displaystring(11,1,c);
 
  baojing();  //报警扫描     
 //shuju=ReadData();//测试用句无意义 
  }
}
//写数据   
void WriteData(uchar DAT)
{
 Readbusy();
 LCD1602_RS = 1;
 LCD1602_RW = 0;
 LCD1602_IO = DAT;
 LCD1602_E = 0; //若晶振速度太高可以在这后加小的延时
 LCD1602_E = 0; //延时 
 LCD1602_E = 1;
 LCD1602_E=1;
 LCD1602_E=0;
}
//写指令    
void WriteCommand(uchar command,BuysC) //BuysC为0时忽略忙检测
{
 LCD1602_IO=0x00;
 if (BuysC) 
 Readbusy(); //根据需要检测忙
 LCD1602_RS = 0;
 LCD1602_RW = 0;
 LCD1602_IO = command;
 LCD1602_E = 0;
 LCD1602_E = 0;
 LCD1602_E = 1; 
 LCD1602_E = 1;
 LCD1602_E=0;
}
//读数据   
uchar ReadData(void)
{
Readbusy();
 LCD1602_RS = 1; 
 LCD1602_RW = 1;
 LCD1602_E = 0;
 LCD1602_E = 0;
 LCD1602_E = 1;
 delayms(1);
 LCD1602_E = 0;
 return(LCD1602_IO);
}
//读忙 
void Readbusy(void)
{
 LCD1602_IO = 0xff; 
 LCD1602_RS = 0;
 LCD1602_RW = 1;
 LCD1602_E = 0;
 LCD1602_E = 0;
 LCD1602_E = 1;
 delayms(2);
 while (LCD1602_IO&0x80); //检测忙信号   
  LCD1602_E = 0;
}
 //初始化 
void LCD1602_Init(void) //LCM初始化
{
 Delay400Ms();
 LCD1602_E = 0;
 LCD1602_IO=0x00;
 WriteCommand(0x38,0); //三次显示模式设置,不检测忙信号
 Delay5Ms();
 WriteCommand(0x38,0);
 Delay5Ms(); 
 WriteCommand(0x38,0);
 Delay5Ms();
 WriteCommand(0x38,1); //显示模式设置,开始要求每次检测忙信号
 Delay5Ms();
 WriteCommand(0x08,1); //关闭显示   ]  
 Delay5Ms();
 WriteCommand(0x01,1); //显示清屏    
 Delay5Ms();
 WriteCommand(0x06,1); // 显示光标移动设置     
 Delay5Ms();
 WriteCommand(0x0f,1); // 显示开及光标设置     
 Delay5Ms();
}
//按指定位置显示一个字符  
void DisplayOneChar(uchar X, uchar Y, uchar DData)
{
 Y &= 0x01;
 X &= 0x0f; //限制X不能大于15,Y不能大于1   
 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
 X |= 0x80; // 算出指令码
 WriteCommand(X, 0); //这里不检测忙信号,发送地址码   
 WriteData(DData);
}
//按指定位置显示一串字符  
void Displaystring(uchar X, uchar Y, uchar code *DData)
{
 uchar ListLength;
  ListLength = 0;
 Y &= 0x01;
 X &= 0x0f; //限制X不能大于15,Y不能大于1
 while (DData[ListLength]>0x20) //若到达字串尾则退出  
  {
   if (X <= 0x0f) //X坐标应小于0x0f   
    {
     DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
     ListLength++;
     X++;
    }
  }
}
//5ms延时
void Delay5Ms(void)
{
 unsigned int t = 5552;
 while(t--);
}
//400ms延时
void Delay400Ms(void)
{
  uchar i = 5;
  uint j;
  while(i--)
   {
  j=7269;
  while(j--);
   }
 }
 

你可能感兴趣的:(我的自学实践)