找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

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

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:69265 發(fā)表于 2014-11-23 18:12 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
#include<reg51.h>                                                                    //包含單片機(jī)寄存器的頭文件
#include<intrins.h>                                                                  //包含_nop_()函數(shù)定義的頭文件
unsigned char code digit[10]={"0123456789"};             //定義字符數(shù)組顯示數(shù)字
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;                                                   //忙碌標(biāo)志位,,將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--);
}

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

}  

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

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





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

360軟件小助手截圖20141123180115.png

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

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

使用道具 舉報(bào)

沙發(fā)
ID:67992 發(fā)表于 2014-11-23 19:20 | 只看該作者
我?guī)湍銓?shí)物連接成功。程序沒問題。請查有無接錯(cuò)線。

評分

參與人數(shù) 1威望 +50 黑幣 +50 收起 理由
admin + 50 + 50 回帖助人的獎(jiǎng)勵(lì)!

查看全部評分

回復(fù)

使用道具 舉報(bào)

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

回復(fù)

使用道具 舉報(bào)

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

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

20141123_193953.jpg

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎(jiǎng)勵(lì)!

查看全部評分

回復(fù)

使用道具 舉報(bào)

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

使用道具 舉報(bào)

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

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

使用道具 舉報(bào)

7#
ID:67992 發(fā)表于 2014-11-24 08:15 來自觸屏版 | 只看該作者
和你的一樣配置。12M晶振,STC89C52RC。和單片機(jī)肯定有關(guān)系,如果用1T單片機(jī)估計(jì)不行,晶振應(yīng)該也有關(guān)系,接24M可能也不行。你應(yīng)該查接線和焊接質(zhì)量。如果你用的買的開發(fā)板,有無共用IO現(xiàn)象。
回復(fù)

使用道具 舉報(bào)

8#
ID:67992 發(fā)表于 2014-11-24 08:57 來自觸屏版 | 只看該作者
其實(shí)很好排查。你先單試液晶調(diào)試正常后再掛接18b20。把與溫度有關(guān)的屏蔽,先把液晶調(diào)正常。
回復(fù)

使用道具 舉報(bào)

9#
ID:67992 發(fā)表于 2014-11-24 09:02 來自觸屏版 | 只看該作者
液晶8根數(shù)據(jù)線,3根控制線,用萬用表測一下通不通。測量點(diǎn)單片機(jī)引腳和液晶板針焊點(diǎn),斷電在路測。
回復(fù)

使用道具 舉報(bào)

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

使用道具 舉報(bào)

11#
ID:66060 發(fā)表于 2014-11-26 09:49 | 只看該作者
成功了,應(yīng)該是單片機(jī)的是
回復(fù)

使用道具 舉報(bào)

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

使用道具 舉報(bào)

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

使用道具 舉報(bào)

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

樓主,我現(xiàn)在面臨和你一樣的問題。想請教一下你的解決方法
回復(fù)

使用道具 舉報(bào)

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

,我是焊接出問題了,后來用杜邦線連接調(diào)試成功才發(fā)現(xiàn)的。
回復(fù)

使用道具 舉報(bào)

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

樓主,你大概是哪個(gè)地方焊錯(cuò)了??
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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