久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7862|回復: 15
打印 上一主題 下一主題
收起左側

仿真成功,但是實物連接失敗(LCD只顯示一排(全黑)),請問誰知道是什么原因?

[復制鏈接]
跳轉到指定樓層
樓主
#include<reg51.h>                                                                    //包含單片機寄存器的頭文件
#include<intrins.h>                                                                  //包含_nop_()函數定義的頭文件
unsigned char code digit[10]={"0123456789"};             //定義字符數組顯示數字
unsigned char code Str[]={"Temperature  Now"};           //說明顯示的是溫度
unsigned char code Error[]={"Error!Check!"};            //說明沒有檢測到DS18B20
unsigned char code Cent[]={0xdf,"C"};                                 //溫度單位
sbit DQ=P3^3;
unsigned char time;            
sbit led1=P1^0;                                                                //LED燈1、2引腳定義
sbit led2=P1^3;
sbit RS=P3^0;                                                          //寄存器選擇位,將RS位定義為P2.0引腳
sbit RW=P3^1;                                                          //讀寫選擇位,將RW位定義為P2.1引腳
sbit E=P3^2;                                                    //使能信號位,將E位定義為P2.2引腳
sbit BF=P2^7;                                                   //忙碌標志位,,將BF位定義為P0.7引腳

void delay1ms(void)   //誤差 0us
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=142;b>0;b--)
            for(a=2;a>0;a--);
}

/*****函數功能:延時若干毫秒*****/
void delaynms(unsigned char n)
{
        unsigned char i;
        for(i=0;i<n;i++)
                delay1ms();
}
/*****函數功能:判斷液晶模塊的忙碌狀態 result=1,忙碌;result=0,不忙*****/
bit BusyTest(void)
{
    bit result;
        RS=0;                                                               //根據規定,RS為低電平,RW為高電平時,可以讀狀態
    RW=1;
    E=1;                                                                //E=1,才允許讀寫
    _nop_();                                                                   //空操作
    _nop_();
    _nop_();
    _nop_();                                                                   //空操作四個機器周期,給硬件反應時間       
    result=BF;                                                          //將忙碌標志電平賦給result
           E=0;                                                                 //將E恢復低電平
        return result;
}
/*****函數功能:將模式設置指令或顯示地址寫入液晶模塊******/
void WriteInstruction (unsigned char dictate)
{   
    while(BusyTest()==1);                                   //如果忙就等待
        RS=0;                                                          //根據規定,RS和R/W同時為低電平時,可以寫入指令
        RW=0;   
        E=0;                                                           //E置低電平(根據表8-6,寫指令時,E為高脈沖,
                                                                   // 就是讓E從0到1發生正跳變,所以應先置"0"
         _nop_();
        _nop_();                                                       //空操作兩個機器周期,給硬件反應時間
        P2=dictate;                                                    //將數據送入P2口,即寫入指令或地址
        _nop_();
        _nop_();
        _nop_();
        _nop_();                                                       //空操作四個機器周期,給硬件反應時間
        E=1;                                                           //E置高電平
        _nop_();
        _nop_();
        _nop_();
        _nop_();                                                       //空操作四個機器周期,給硬件反應時間
        E=0;                                                         //當E由高電平跳變成低電平時,液晶模塊開始執行命令
}
/*****函數功能:指定字符顯示的實際地址*****/
void WriteAddress(unsigned char x)
{
        WriteInstruction(x|0x80);                                 //顯示位置的確定方法規定為"80H+地址碼x"
}
/*****函數功能:將數據(字符的標準ASCII碼)寫入液晶模塊*****/
void WriteData(unsigned char y)
{
        while(BusyTest()==1);  
        RS=1;                                                           //RS為高電平,RW為低電平時,可以寫入數據
        RW=0;
        E=0;                                                            //E置低電平(根據表8-6,寫指令時,E為高脈沖,
                                                                     // 就是讓E從0到1發生正跳變,所以應先置"0"
        P2=y;                                                           //將數據送入P2口,即將數據寫入液晶模塊
        _nop_();
        _nop_();
         _nop_();
         _nop_();                                                       //空操作四個機器周期,給硬件反應時間
        E=1;                                                                   //E置高電平
        _nop_();
        _nop_();
        _nop_();
        _nop_();                                                        //空操作四個機器周期,給硬件反應時間
        E=0;                                                            //當E由高電平跳變成低電平時,液晶模塊開始執行命令
}
/*****函數功能:對LCD的顯示模式進行初始化設置*****/
void LcdInitiate(void)
{
    E=0;
        RS=1;
        RW=1;
        delaynms(15);                                       //延時15ms,首次寫指令時應給LCD一段較長的反應時間
    WriteInstruction(0x38);                             //顯示模式設置:16×2顯示,5×7點陣,8位數據接口
        delaynms(5);                                        //延時5ms ,給硬件一點反應時間
    WriteInstruction(0x38);
        delaynms(5);                                               //連續2次,確保初始化成功
        WriteInstruction(0x0c);                             //顯示模式設置:顯示開,無光標,光標不閃爍
        delaynms(5);                                               //延時5ms ,給硬件一點反應時間
        WriteInstruction(0x06);                             //顯示模式設置:光標右移,字符不移
        delaynms(5);                                        //延時5ms ,給硬件一點反應時間
        WriteInstruction(0x01);                             //清屏幕指令,將以前的顯示內容清除
        delaynms(5);                                             //延時5ms ,給硬件一點反應時間

}  

/*****函數功能:將DS18B20傳感器初始化,讀取應答信號*****/
bit Init_DS18B20(void)       
{
        bit flag;                                                         //儲存DS18B20是否存在的標志,flag=0,表示存在;flag=1,表示不存在
        DQ = 1;                                                           //先將數據線拉高
        for(time=0;time<2;time++)                                 //略微延時約6微秒
                ;
        DQ = 0;                                                           //再將數據線從高拉低,要求保持480~960us
        for(time=0;time<200;time++)                          //略微延時約600微秒
                ;                                                                 //以向DS18B20發出一持續480~960us的低電平復位脈沖
        DQ = 1;                                                           //釋放數據線(將數據線拉高)
        for(time=0;time<10;time++)
                ;                                                                          //延時約30us(釋放總線后需等待15~60us讓DS18B20輸出存在脈沖)
        flag=DQ;                                                          //讓單片機檢測是否輸出了存在脈沖(DQ=0表示存在)      
        for(time=0;time<200;time++)                          //延時足夠長時間,等待存在脈沖輸出完畢
        ;
        return (flag);                                                    //返回檢測成功標志
}
/*****函數功能:從DS18B20讀取一個字節數據*****/
unsigned char ReadOneChar(void)
{
        unsigned char i=0;       
        unsigned char dat;                                          //儲存讀出的一個字節數據
        for (i=0;i<8;i++)
        {                  
                DQ =1;                                                       // 先將數據線拉高
                _nop_();                                                    //等待一個機器周期         
                DQ = 0;                                                      //單片機從DS18B20讀書據時,將數據線從高拉低即啟動讀時序
                dat>>=1;
                _nop_();                                                     //等待一個機器周期                  
                DQ = 1;                                                     //將數據線"人為"拉高,為單片機檢測DS18B20的輸出電平作準備
                for(time=0;time<2;time++)
                        ;                                                              //延時約6us,使主機在15us內采樣
                if(DQ==1)
                        dat|=0x80;                                          //如果讀到的數據是1,則將1存入dat
                else
                        dat|=0x00;                                                //如果讀到的數據是0,則將0存入dat
                                                                                            
                for(time=0;time<8;time++)
                        ;                                                      //延時3us,兩個讀時序之間必須有大于1us的恢復期       
        }                            
        return(dat);                                                    //返回讀出的十進制數據
}
/*****函數功能:向DS18B20寫入一個字節數據*****/  
WriteOneChar(unsigned char dat)
{
        unsigned char i=0;
        for (i=0; i<8; i++)
        {
                DQ =1;                                                         // 先將數據線拉高
                _nop_();                                                     //等待一個機器周期         
                DQ=0;                                                          //將數據線從高拉低時即啟動寫時序      
                DQ=dat&0x01;                                                   //利用與運算取出要寫的某位二進制數據,
                                                                       //并將其送到數據線上等待DS18B20采樣       
                for(time=0;time<10;time++)       
                        ;                                                                //延時約30us,DS18B20在拉低后的約15~60us期間從數據線上采樣
                        DQ=1;                                                  //釋放數據線                    
                for(time=0;time<1;time++)
                        ;                                                                //延時3us,兩個寫時序間至少需要1us的恢復期
                        dat>>=1;                                               //將dat中的各二進制位數據右移1位
        }
        for(time=0;time<4;time++)
                        ;                                                                //稍作延時,給硬件一點反應時間
}
/*****函數功能:顯示沒有檢測到DS18B20*****/   
void display_error(void)
{
        unsigned char i;
        WriteAddress(0x00);                                            //寫顯示地址,將在第1行第1列開始顯示
        i = 0;                                                        //從第一個字符開始顯示
        while(Error[i] != '\0')                                  //只要沒有寫到結束標志,就繼續寫
        {                                               
                WriteData(Error[i]);                                   //將字符常量寫入LCD
                i++;                                                 //指向下一個字符
                delaynms(100);                                        //延時100ms較長時間,以看清關于顯示的說明
        }       
        while(1)                                                      //進入死循環,等待查明原因
                ;
}
/*****函數功能:顯示"Temperature Now"提示信息*****/   
void display_explain(void)
{
        unsigned char i;
        WriteAddress(0x00);                                            //寫顯示地址,將在第1行第1列開始顯示
        i = 0;                                                        //從第一個字符開始顯示
        while(Str[i] != '\0')                                          //只要沒有寫到結束標志,就繼續寫
        {                                               
                WriteData(Str[i]);                                   //將字符常量寫入LCD
                i++;                                                 //指向下一個字符
                delaynms(100);                                        //延時100ms較長時間,以看清關于顯示的說明
        }       
}
/*****函數功能:顯示小數點*****/
void display_dot(void)
{         
        WriteAddress(0x48);                                                  //寫顯示地址,將在第2行第9列開始顯示                  
        WriteData('.');                                              //將小數點的字符常量寫入LCD
        delaynms(50);                                                 //延時1ms給硬件一點反應時間               
}
/*****函數功能:顯示溫度的單位*****/   
void display_cent(void)
{
        unsigned char i;   
        WriteAddress(0x4a);                                        //寫顯示地址,將在第2行第11列開始顯示       
        i = 0;                                                    //從第一個字符開始顯示
        while(Cent[i] != '\0')                                     //只要沒有寫到結束標志,就繼續寫
        {                                       
                WriteData(Cent[i]);                             //將字符常量寫入LCD
                i++;                                                //指向下一個字符
                delaynms(50);                                        //延時1ms給硬件一點反應時間
        }       
}
/*****函數功能:顯示溫度的整數部分*****/
void display_temp1(unsigned char x)
{
        unsigned char j,k,l;                                     //j,k,l分別儲存溫度的百位、十位和個位
        j=x/100;                                                      //取百位
        k=(x%100)/10;                                                    //取十位
        l=x%10;                                                     //取個位  
        WriteAddress(0x45);                                            //寫顯示地址,將在第2行第6列開始顯示
        WriteData(digit[j]);                                    //將百位數字的字符常量寫入LCD
        WriteData(digit[k]);                                    //將十位數字的字符常量寫入LCD
        WriteData(digit[l]);                                    //將個位數字的字符常量寫入LCD
        delaynms(50);                                                 //延時1ms給硬件一點反應時間     
}
/*****函數功能:顯示溫度的小數點后一位*****/
void display_temp2(unsigned char x)
{
        WriteAddress(0x49);                                      //寫顯示地址,將在第2行第11列開始顯示
        WriteData(digit[x]);                                     //將小數部分的第一位數字字符常量寫入LCD
        delaynms(50);                                                  //延時1ms給硬件一點反應時間
}
/*****函數功能:做好讀溫度的準備*****/
void ReadyReadTemp(void)
{
        Init_DS18B20();                                             //將DS18B20初始化
        WriteOneChar(0xCC);                                         // 跳過讀序號列號的操作
        WriteOneChar(0x44);                                         // 啟動溫度轉換          
        for(time=0;time<100;time++)
                ;                                                                         //溫度轉換需要一點時間
        Init_DS18B20();                                             //將DS18B20初始化
        WriteOneChar(0xCC);                                         //跳過讀序號列號的操作
        WriteOneChar(0xBE);                                         //讀取溫度寄存器,前兩個分別是溫度的低位和高位       
}

void main(void)
{          
        unsigned char TL;                                             //儲存暫存器的溫度低位
        unsigned char TH;                                            //儲存暫存器的溫度高位
        unsigned char TN;                                              //儲存溫度的整數部分
        unsigned char TD;                                       //儲存溫度的小數部分
        LcdInitiate();                                                 //將液晶初始化
        delaynms(4);                                                //延時5ms給硬件一點反應時間       
        if(Init_DS18B20()==1)
        display_error();
        display_explain();
        while(1)                                                //不斷檢測并顯示溫度
        {       
                ReadyReadTemp();                                     //讀溫度準備
                TL=ReadOneChar();                                    //先讀的是溫度值低位
                TH=ReadOneChar();                                    //接著讀的是溫度值高位
                if(TH&0xf8)                                                        //溫度為負時,數據處理
                {       
                        P1=0xff;                                                //拉低P1引腳,LED燈滅
                        TH=~TH;
                        TL=~TL+1;
                        WriteAddress(0x44);
                        WriteData('-');
                        TN=TH*16+TL/16;
                        if(TN>=1)                                                //溫度低于-1度,LED2閃爍
                        {
                                led2=0;
                                delaynms(1000);
                                led2=~led2;
                        }
                        TD=(TL%16)*10/16;
                        display_temp1(TN);
                        display_temp2(TD);
                        delaynms(10);
                }
                else
                {
                        P1=0xff;
                        TN=TH*16+TL/16;                              //實際溫度值=(TH*256+TL)/16,即:TH*16+TL/16
                                                                                        //這樣得出的是溫度的整數部分,小數部分被丟棄了
                        if(TN>=36)                                                //若溫度高于38度,LED1閃爍
                        {
                                led1=0;
                                delaynms(1000);
                                led1=~led1;
                        }                                    
                        TD=(TL%16)*10/16;                           //計算溫度的小數部分,將余數乘以10再除以16取整,
                                                                //這樣得到的是溫度小數部分的第一位數字(保留1位小數)
                        WriteAddress(0x44);
                        WriteData('+');
                        display_temp1(TN);                            //顯示溫度的整數部分
                        display_temp2(TD);                            //顯示溫度的小數部分
                        delaynms(10);  
                }   
                display_dot();                                               //顯示溫度的小數點
                display_cent();                                              //顯示溫度的單位         
        }                                  
}





360軟件小助手截圖20141123180115.png (54.91 KB, 下載次數: 179)

360軟件小助手截圖20141123180115.png

2.png (51.63 KB, 下載次數: 184)

2.png
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:67992 發表于 2014-11-23 19:20 | 只看該作者
我幫你實物連接成功。程序沒問題。請查有無接錯線。

評分

參與人數 1威望 +50 黑幣 +50 收起 理由
admin + 50 + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

板凳
ID:67992 發表于 2014-11-23 19:43 | 只看該作者

回復

使用道具 舉報

地板
ID:66729 發表于 2014-11-23 20:22 | 只看該作者
我也成功了,用在系統板子上。。哈哈,我的是12864。。唉
  所以,你還是看下接線吧

20141123_193953.jpg (36.28 KB, 下載次數: 147)

20141123_193953.jpg

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

5#
ID:1 發表于 2014-11-23 22:09 | 只看該作者
我估計肯定是液晶屏的排針沒有焊接好的緣故.
回復

使用道具 舉報

6#
ID:69265 發表于 2014-11-23 23:21 | 只看該作者

請問你用的是什么單片機?我用的是STC89C52RC單片機(外接12M晶振),然后根據仿真圖一一對應的引腳接的。和單片機或晶振有關系嗎?或者有什么地方該注意的嗎?我學習單片機不深,還請賜教!!
回復

使用道具 舉報

7#
ID:67992 發表于 2014-11-24 08:15 來自手機 | 只看該作者
和你的一樣配置。12M晶振,STC89C52RC。和單片機肯定有關系,如果用1T單片機估計不行,晶振應該也有關系,接24M可能也不行。你應該查接線和焊接質量。如果你用的買的開發板,有無共用IO現象。
回復

使用道具 舉報

8#
ID:67992 發表于 2014-11-24 08:57 來自手機 | 只看該作者
其實很好排查。你先單試液晶調試正常后再掛接18b20。把與溫度有關的屏蔽,先把液晶調正常。
回復

使用道具 舉報

9#
ID:67992 發表于 2014-11-24 09:02 來自手機 | 只看該作者
液晶8根數據線,3根控制線,用萬用表測一下通不通。測量點單片機引腳和液晶板針焊點,斷電在路測。
回復

使用道具 舉報

10#
ID:66060 發表于 2014-11-26 09:47 | 只看該作者
很好用,真的和好用法
回復

使用道具 舉報

11#
ID:66060 發表于 2014-11-26 09:49 | 只看該作者
成功了,應該是單片機的是
回復

使用道具 舉報

12#
ID:69706 發表于 2014-11-30 19:12 | 只看該作者
檢查你的液晶顯示屏的連接,是否有錯?
回復

使用道具 舉報

13#
ID:69265 發表于 2014-11-30 22:03 | 只看該作者
謝謝各位,問題已經解決了!!
回復

使用道具 舉報

14#
ID:87748 發表于 2015-9-4 15:39 | 只看該作者
shifanghui 發表于 2014-11-30 22:03
謝謝各位,問題已經解決了!!

樓主,我現在面臨和你一樣的問題。想請教一下你的解決方法
回復

使用道具 舉報

15#
ID:69265 發表于 2015-9-15 21:36 | 只看該作者
Eve 發表于 2015-9-4 15:39
樓主,我現在面臨和你一樣的問題。想請教一下你的解決方法

,我是焊接出問題了,后來用杜邦線連接調試成功才發現的。
回復

使用道具 舉報

16#
ID:154180 發表于 2016-12-12 17:36 | 只看該作者
shifanghui 發表于 2015-9-15 21:36
,我是焊接出問題了,后來用杜邦線連接調試成功才發現的。

樓主,你大概是哪個地方焊錯了??
回復

使用道具 舉報

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

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 浴室洗澡偷拍一区二区 | 性色av一区二区三区 | 91aiai| 亚洲精品国产成人 | 日韩欧美三区 | 2019精品手机国产品在线 | 亚洲精品在线免费 | 日本一区二区不卡 | 成人一区二 | 在线午夜| 精品国产乱码久久久久久丨区2区 | 日韩av在线一区 | www.亚洲精品 | 久久精品一区二区三区四区 | 91视频在线看 | 天天亚洲 | 国产精品久久久久一区二区三区 | 91丨九色丨国产在线 | 精精国产视频 | 精品在线一区二区三区 | 国产丝袜一区二区三区免费视频 | 日韩欧美在线观看视频 | 久久黄色网| 狠狠av | 国产一级一级毛片 | 欧美日韩国产一区二区三区 | 国产农村妇女精品一二区 | 在线日韩精品视频 | 久久久久久中文字幕 | 免费在线黄 | 免费精品 | 国产成人精品一区二区三 | 日本一区二区电影 | 日韩福利 | 欧美日韩在线精品 | 夫妻午夜影院 | 亚洲欧美bt | 天天干天天爱天天 | 日本中文字幕在线视频 | 日韩一区二区三区视频 | 久久999 |