標題: 學習做的DS18b20+LCD1602溫度顯示器,設(shè)計出來只亮背光燈,不出結(jié)果 [打印本頁]

作者: Ambercat    時間: 2018-1-1 14:01
標題: 學習做的DS18b20+LCD1602溫度顯示器,設(shè)計出來只亮背光燈,不出結(jié)果
求位大神幫忙看看是哪里錯了,按照這個電路圖做出來的板子接上電源后,1602只有一個背光燈亮,在proteus上仿真也是這種情況,LCD只有一個背光燈亮,附上程序

#include <AT89X52.h>       //調(diào)用51單片機的頭文件
#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總線開始復位       
   i=200;                                             //保持DQ低大約870uS,符合不低于48US的要求
   while(i>0)                             //保持DQ低大約870uS,符合不低于48US的要求
       i--;                               //保持DQ低大約870uS,符合不低于48US的要求            
   ds18b20=1;                             //拉高準備接收數(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為復位成功,k=1為復位失敗
}

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ù)做準備
                _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)          //復位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)          //復位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;                                        //如果復位失敗,溫度參數(shù)清零
      temp2=0;                                        //如果復位失敗,溫度參數(shù)清零       
        }
}

void LCD1602_busy(void)
{
     P0_7=1;              //將P0.7置1,為讀狀態(tài)做準備
     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;                 //讀完以后,恢復E的電平
}

void LCD1602_Write_com(unsigned char combuf)
{
     RS=0;                //選擇指令寄存器
     RW=0;                //選擇寫狀態(tài)
     P0=combuf;           //將命令字通過P0口送至DB
     E=1;                 //E高電平將命令字寫入1602液晶
     E=0;                 //寫完以后,恢復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;                 //寫完以后,恢復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點陣顯示
     Delay(50);                //調(diào)用延時函數(shù)
     LCD1602_Write_com(0x38);       //8位數(shù)據(jù)總線,兩行顯示模式,5*7點陣顯示
     Delay(50);                //調(diào)用延時函數(shù)
     LCD1602_Write_com(0x38);       //8位數(shù)據(jù)總線,兩行顯示模式,5*7點陣顯示
     LCD1602_Write_com_busy(0x38);  //8位數(shù)據(jù)總線,兩行顯示模式,5*7點陣顯示
     LCD1602_Write_com_busy(0x08);  //顯示功能關(guān),無光標
     LCD1602_Write_com_busy(0x01);  //清屏
     LCD1602_Write_com_busy(0x06);  //寫入新的數(shù)據(jù)后,光標右移,顯示屏不移動
     LCD1602_Write_com_busy(0x0C);  //顯示功能開,無光標
}


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ù),單片機開機后就是從這個函數(shù)開始運行
{
   LCD1602_init();        //調(diào)用1602液晶初始化函數(shù)
   while(1)               //死循環(huá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

作者: cjjcjj1    時間: 2018-1-1 17:56
提示: 作者被禁止或刪除 內(nèi)容自動屏蔽
作者: 步步為盈    時間: 2018-1-1 21:29
樓主如果是初學,建議程序分段調(diào)試。避免錯誤判斷,提高效率,和成功率
作者: 1123212143255    時間: 2018-1-2 06:39
先測量晶振兩腳電壓是否2.5v3.5v左右,如果是,硬件沒問題。
作者: few    時間: 2018-1-2 08:56
從LCD1602_init函數(shù)先調(diào)試一下吧,慢慢來




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1