找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4555|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

學(xué)習(xí)做的DS18b20+LCD1602溫度顯示器,設(shè)計出來只亮背光燈,不出結(jié)果

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
求位大神幫忙看看是哪里錯了,按照這個電路圖做出來的板子接上電源后,1602只有一個背光燈亮,在proteus上仿真也是這種情況,LCD只有一個背光燈亮,附上程序

#include <AT89X52.h>       //調(diào)用51單片機(jī)的頭文件
#include <Intrins.h>  
//---------------------------------------
//1602液晶相關(guān)I/O設(shè)置
sbit E=P2^2;               //1602液晶的E腳接在P2.2口上
sbit RW=P2^1;              //1602液晶的RW腳接在P2.1口上
sbit RS=P2^0;              //1602液晶的RS腳接在P2.0口上
//---------------------------------------
sbit ds18b20=P3^7;       
//---------------------------------------
//1602液晶寄存器設(shè)置
unsigned char DISbuf;     //設(shè)置8位的unsigend char型寄存器用來暫存1602要顯示的內(nèi)容
//---------------------------------------          
unsigned char temp1;
unsigned char temp2;
unsigned char code table[16]={0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,9};

void Delay(unsigned int nTimeDelay)
{
    unsigned int i;
    while (nTimeDelay--)
        for (i=0;i<125;i++);
}

bit Reset(void)
{
        unsigned int i;
   bit k;
   ds18b20=0;                             //拉低DQ總線開始復(fù)位       
   i=200;                                             //保持DQ低大約870uS,符合不低于48US的要求
   while(i>0)                             //保持DQ低大約870uS,符合不低于48US的要求
       i--;                               //保持DQ低大約870uS,符合不低于48US的要求            
   ds18b20=1;                             //拉高準(zhǔn)備接收數(shù)據(jù)   
   i=18;                                            //大約80uS后
   while(i>0)                                    //大約80uS后
       i--;                                      //大約80uS后
   k=ds18b20;                               //讀出數(shù)據(jù)并保存   
   i=91;                                                    //維持約400US,符合總讀時隙不低于480US的要求
   while(i>0)                                    //維持約400US,符合總讀時隙不低于480US的要求
       i--;                                      //維持約400US,符合總讀時隙不低于480US的要求
   return k;               //k=0為復(fù)位成功,k=1為復(fù)位失敗
}

unsigned char ReadByte(void)
{
        unsigned int i;
   unsigned char j,buf=0;
   for(j=0;j<8;j++)                        //接收8次還原一個字節(jié)數(shù)據(jù)
   {
                buf=buf>>1;                          //接收前,想將接收緩沖區(qū)右移
                ds18b20=0;                                 //拉低      
      _nop_();                       //維持2US,符合大于1US小于15US的規(guī)范
      _nop_();                       //維持2US,符合大于1US小于15US的規(guī)范
      _nop_();                       //維持2US,符合大于1US小于15US的規(guī)范
           _nop_();                       //維持2US,符合大于1US小于15US的規(guī)范
      ds18b20=1;                                  //拉高,為讀數(shù)據(jù)做準(zhǔn)備
                _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
      _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
      _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
           _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
                _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
      _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
      _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
           _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
                _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
      _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
      _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
           _nop_();                       //維持6US,符合大于1US小于15US的規(guī)范
                if(ds18b20==1) buf|=0x80;  //讀出1位數(shù)據(jù)保存于buf中
                i=12;                                          //維持約52US,符合總讀時隙不低于60US的要求
      while(i>0)                          //維持約52US,符合總讀時隙不低于60US的要求
              i--;                             //維持約52US,符合總讀時隙不低于60US的要求
        }
   return buf;             //退出的同時將接收緩沖區(qū)參數(shù)返回
}


void WriteByte(unsigned char dat)
{
        unsigned int i;
   unsigned char j;
   for(j=0;j<8;j++)
   {            
                if(dat&0x01)                        //如果寫1
      {      
                   ds18b20=0;                         //拉低      
         _nop_();               //維持2US,符合大于1US小于15US的規(guī)范
         _nop_();               //維持2US,符合大于1US小于15US的規(guī)范
         _nop_();               //維持2US,符合大于1US小于15US的規(guī)范
                    _nop_();               //維持2US,符合大于1US小于15US的規(guī)范
         ds18b20=1;                          //拉高        
         i=14;                                  //維持約63US,符合不低于60US的要求
         while(i>0)                  //維持約63US,符合不低于60US的要求
                 i--;                     //維持約63US,符合不低于60US的要求
                }
      else                                                //如果寫0
      {            
                        ds18b20=0;                         //拉低                 
         i=14;                                        //維持約63US,符合不低于60US的要求
         while(i>0)                        //維持約63US,符合不低于60US的要求
                 i--;                            //維持約63US,符合不低于60US的要求        
         ds18b20=1;                         //拉高                
         _nop_();               //維持2US,符合大于1US的規(guī)范
         _nop_();               //維持2US,符合大于1US的規(guī)范
         _nop_();               //維持2US,符合大于1US的規(guī)范
                    _nop_();               //維持2US,符合大于1US的規(guī)范
      }
                dat=dat>>1;                                //寫入字節(jié)右移1位
        }
}


bit Convert(void)
{   
        if(Reset()==0)          //復(fù)位DS18B20
        {               
            WriteByte(0xcc);                //寫入跳過序列號命令字 Skip Rom
      WriteByte(0x44);                //寫入溫度轉(zhuǎn)換命令字 Convert T  
                  return 1;            //啟動溫度轉(zhuǎn)換成功
        }
        else
        {          
                  return 0;            //啟動溫度轉(zhuǎn)換失敗
        }
}


void ReadFlash(void)
{   
        unsigned char Lsb,Msb;       
   if(Reset()==0)          //復(fù)位DS18B20
        {
      WriteByte(0xcc);                //寫入跳過序列號命令字 Skip Rom
      WriteByte(0xbe);                //寫入讀取數(shù)據(jù)令字 Read Scratchpad
      Lsb=ReadByte();                //讀出第一個字節(jié)暫存于LSB
      Msb=ReadByte();                //讀出第二個字節(jié)暫存于MSB       
                  temp1=Lsb&0x0f;                //temp1內(nèi)裝溫度參數(shù)的小數(shù)部分
      temp2=(Lsb>>4)|(Msb<<4);//temp2內(nèi)裝溫度參數(shù)的整數(shù)部分          
        }       
        else
        {
                temp1=0;                                        //如果復(fù)位失敗,溫度參數(shù)清零
      temp2=0;                                        //如果復(fù)位失敗,溫度參數(shù)清零       
        }
}

void LCD1602_busy(void)
{
     P0_7=1;              //將P0.7置1,為讀狀態(tài)做準(zhǔn)備
     RS=0;                //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
     RW=1;                //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
     E=1;                 //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
     while(P0_7==1);      //由P0.7讀入1,表示1602液晶忙,需要等待
     E=0;                 //讀完以后,恢復(fù)E的電平
}

void LCD1602_Write_com(unsigned char combuf)
{
     RS=0;                //選擇指令寄存器
     RW=0;                //選擇寫狀態(tài)
     P0=combuf;           //將命令字通過P0口送至DB
     E=1;                 //E高電平將命令字寫入1602液晶
     E=0;                 //寫完以后,恢復(fù)E的電平
}

void LCD1602_Write_com_busy(unsigned char combuf)
{
     LCD1602_busy();            //調(diào)用忙檢測函數(shù)
     LCD1602_Write_com(combuf); //調(diào)用忙檢測函數(shù)
}


void LCD1602_Write_data_busy(unsigned char databuf)
{
     LCD1602_busy();      //調(diào)用忙檢測函數(shù)
     RS=1;                //選擇數(shù)據(jù)寄存器
     RW=0;                //選擇寫狀態(tài)
     P0=databuf;          //將命令字通過P0口送至DB
     E=1;                 //E高電平將命令字寫入1602液晶
     E=0;                 //寫完以后,恢復(fù)E的電平
}


void LCD1602_Write_address(unsigned char x,unsigned char y)
{
     x&=0x0f;             //列地址限制在0-15間
     y&=0x01;             //行地址限制在0-1間
     if(y==0)             //如果是第一行
         LCD1602_Write_com_busy(x|0x80);        //將列地址寫入
     else                 //如果是第二行
         LCD1602_Write_com_busy((x+0x40)|0x80); //將列地址寫入
}


void LCD1602_init(void)
{
     Delay(150);               //調(diào)用延時函數(shù)
     LCD1602_Write_com(0x38);       //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
     Delay(50);                //調(diào)用延時函數(shù)
     LCD1602_Write_com(0x38);       //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
     Delay(50);                //調(diào)用延時函數(shù)
     LCD1602_Write_com(0x38);       //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
     LCD1602_Write_com_busy(0x38);  //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
     LCD1602_Write_com_busy(0x08);  //顯示功能關(guān),無光標(biāo)
     LCD1602_Write_com_busy(0x01);  //清屏
     LCD1602_Write_com_busy(0x06);  //寫入新的數(shù)據(jù)后,光標(biāo)右移,顯示屏不移動
     LCD1602_Write_com_busy(0x0C);  //顯示功能開,無光標(biāo)
}


void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf)
{
     LCD1602_Write_address(x,y);    //先將地址信息寫入
     LCD1602_Write_data_busy(buf);  //再寫入要顯示的數(shù)據(jù)
}


void main(void)            //主函數(shù),單片機(jī)開機(jī)后就是從這個函數(shù)開始運(yùn)行
{
   LCD1602_init();        //調(diào)用1602液晶初始化函數(shù)
   while(1)               //死循環(huán),單片機(jī)初始化后,將一直運(yùn)行這個死循環(huán)
   {
      if(Convert()==1)                                                 //啟動轉(zhuǎn)換
                {             
                    ReadFlash();                       //讀取溫度                           
         if(temp2>99) temp2=99;                         
                         if(temp1>15) temp1=0;                                                 
                        LCD1602_Disp(0,0,temp2/10+'0');  //溫度整數(shù)部分十位                               
                   LCD1602_Disp(1,0,temp2%10+'0');  //溫度整數(shù)部分個位
                        LCD1602_Disp(2,0,'.');  //.               
                        LCD1602_Disp(3,0,table[temp1]+'0');  //溫度小數(shù)部分
                        LCD1602_Disp(4,0,0xdf);   //.
                        LCD1602_Disp(5,0,0x43);   //C                                                                 
            }   
    }
}


P6WM$}8M%JPHGHR4IWH[JKP.png (136.58 KB, 下載次數(shù): 57)

P6WM$}8M%JPHGHR4IWH[JKP.png

P6%PQP4)4EUI2UPRU56W3`L.png (53.18 KB, 下載次數(shù): 62)

P6%PQP4)4EUI2UPRU56W3`L.png

HQF(JP4%SGVGJUQ3F4D(0ZG.png (447.54 KB, 下載次數(shù): 64)

HQF(JP4%SGVGJUQ3F4D(0ZG.png
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:82765 發(fā)表于 2018-1-1 17:56 | 只看該作者
提示: 作者被禁止或刪除 內(nèi)容自動屏蔽
回復(fù)

使用道具 舉報

板凳
ID:261000 發(fā)表于 2018-1-1 21:29 | 只看該作者
樓主如果是初學(xué),建議程序分段調(diào)試。避免錯誤判斷,提高效率,和成功率
回復(fù)

使用道具 舉報

地板
ID:126608 發(fā)表于 2018-1-2 06:39 | 只看該作者
先測量晶振兩腳電壓是否2.5v3.5v左右,如果是,硬件沒問題。
回復(fù)

使用道具 舉報

5#
ID:269976 發(fā)表于 2018-1-2 08:56 | 只看該作者
從LCD1602_init函數(shù)先調(diào)試一下吧,慢慢來
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表