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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

DS18B20仿真后,LCD顯示的溫度和實際模擬溫度不一致,跪求大佬指教啊

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:665413 發(fā)表于 2019-12-27 18:54 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
仿真的實驗現(xiàn)象圖已經(jīng)放在后面了,大佬幫我看看問題啊

現(xiàn)在就是LCD顯示的溫度和實際模擬溫度不一致,





/**************************************************/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define delayNop(); {_nop_();_nop_();_nop_();_nop_();};

uchar code table[]=" ERROR!!!       ";
uchar code table1[]="xianzaiwendu    ";
uchar code table2[]="Temp=    .  Cent";
uchar code table3[10]="0123456789";

sbit lcd_rs=P1^0;
//sbit lcd_rw=P1^1;
sbit lcd_en=P2^5;
sbit DQ=P2^2;
uchar num,time;
void delay(uint t)
{
unsigned char n;
   while(t--)
   {
     for(n = 0; n<250; n++)
    {
      _nop_();
      _nop_();
     _nop_();
      _nop_();
    }
   }
}

void write_com(uchar com)    //寫命令
{
////lcd_rw=0;
//delay(5);
        lcd_rs=0;
        lcd_en=0;
        _nop_();
        _nop_();
        P0=com;
        delayNop();
        lcd_en=1;  
        delay(1);
        lcd_en=0;
}

void write_date(uchar date)      //寫數(shù)據(jù)
{
//lcd_rw=0;
// delay(5);
  lcd_rs=1;
  lcd_en=0;
  _nop_();
  _nop_();

   P0=date;        
   delayNop();
        lcd_en=1;                                                         
        delay(1);
        lcd_en=0;               
}

void init()       //初始化函數(shù)
{
// dula=0;
// wela=0;
lcd_en=0;  //可以試試不加這一句看結(jié)果怎樣
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}

uchar init_DS18bB20()
{
        bit flag;
        DQ=1;                                          //人為拉高
        for(time=0;time<2;time++);                        //稍微延時6US;
        DQ=0;                                                        //認為拉低
        for(time=0;time<200;time++);                          //延時600US給單片機檢測
        DQ=1;                                                                   //被上拉電阻拉高        (仿真里面沒有上拉,有沒有都需要人為拉高)
        for(time=0;time<20;time++);                           // 延時60US檢測
        flag=DQ;                                                                //這時又被DS18B20拉低,
        for(time=0;time<200;time++);                   //延時600US檢測時間
        return flag;                     //返回0表示存在

}

void Write_Byte(uchar dat)                 //寫一個字節(jié),單片機向DS18B20寫命令,確定DS18B20的工作方法之類的
{
unsigned char i=0;
        for (i=0; i<8; i++)
                 {
                  DQ =1;         // 先將數(shù)據(jù)線拉高
                  _nop_();             //等待一個機器周期         
                  DQ=0;          //將數(shù)據(jù)線從高拉低時即啟動寫時序      
                  DQ=dat&0x01;   //利用與運算取出要寫的某位二進制數(shù)據(jù),
                       //并將其送到數(shù)據(jù)線上等待DS18B20采樣        
                 for(time=0;time<10;time++)        
                     ;//延時約30us,DS18B20在拉低后的約15~60us期間從數(shù)據(jù)線上采樣
                  DQ=1;          //釋放數(shù)據(jù)線,也就是被上拉電阻拉高,反正就是要把這個口釋放,然后來執(zhí)行下一個命令                    
                  for(time=0;time<1;time++)
                          ;//延時3us,兩個寫時序間至少需要1us的恢復(fù)期
                  dat>>=1;       //將dat中的各二進制位數(shù)據(jù)右移1位
                 }
          for(time=0;time<4;time++)
                      ; //稍作延時,給硬件一點反應(yīng)時間
}

uchar Read_Byte()
{
        uchar i=0;
        uchar dat;//用來儲存讀出的一個字節(jié),默認為0
        for(i=0;i<8;i++)
        {
                DQ=1;
                _nop_();
                DQ=0;        //讀命令一定得是低電平
                dat>>=1;   //讀取數(shù)據(jù)是從高位開始讀,dat默認是0,也就是0000 0000,
                                 //  這是下標(biāo)是指向最高位的,所以得先右移一位讓出一個位置
                _nop_();        //需要>1US;
                DQ=1;                //又被上拉電阻拉高
           for(time=0;time<2;time++);
                if(DQ==1)                   //由DQ發(fā)送的信號來決定,發(fā)送的是高電平還是低電平
                        dat|=0x80;           //高電平就或0x80,1000 0000
                else
                        dat|=0x00;         //低電平就或,0x00
                for(time=0;time<5;time++);//延時10US左右,因為需要在15US內(nèi)完成讀取
                }                                 
        return dat;
}

void Readyread()//做好讀溫度準(zhǔn)備。。。。可以加在主函數(shù)里面,但是分出來比較清晰明了
{
        init_DS18bB20();
        Write_Byte(0xcc);        //跳過讀序號
        Write_Byte(0x44);   //啟動溫度轉(zhuǎn)換
        for(time=0;time<100;time++);
        init_DS18bB20();           //再初始化一下
        Write_Byte(0xcc);  //跳過讀序號
        Write_Byte(0xbe);  //都溫度寄存器,前兩個分別是溫度的,低,高位
}

void display()                                                //顯示第一行說明
{
        write_com(0x80);
        for(num=0;num<16;num++)
        {
                 write_date(table[num]);
         //        delay(1);
        }  
                while(1);
}

void display1()                                        //顯示第二行說明
{
        write_com(0x80);
        for(num=0;num<16;num++)
        {
                write_date(table1[num]);
          //        delay(1);
        }


}

void display2()
{
        write_com(0x80+0x40);
        for(num=0;num<16;num++)
        {
                  write_date(table2[num]);
                  //delay(1);
        }
}
                                                
void display_temp(uchar x)          //顯示溫度整數(shù)部分
{
        uchar bai,shi,ge;
        bai=x/100;
        shi=(x%100)/10;
        ge=x%10;
        write_com(0x80+0x46);
        write_date(table3[bai]);
        write_date(table3[shi]);
        write_date(table3[ge]);



}

void display1_temp(uchar x)          //顯示溫度小數(shù)部分
{
        write_com(0x80+0x4a);
        write_date(table3[x]);
}



void main()
{
        uchar TL;//儲存暫存器的溫度最高位
        uchar TH;//儲存暫存器的溫度最低位
        uchar TN; //儲存溫度整數(shù)部分
        uchar TD; //儲存溫度小數(shù)部分
        init();
        if(init_DS18bB20()==1)
                display();
        display1();
        display2();
        while(1)
        {
                Readyread();
                TL=Read_Byte();
                TH=Read_Byte();
                TN=TH*16+TL/16;      //實際溫度值=(TH*256+TL)/16,即:TH*16+TL/16
                                          //這樣得出的是溫度的整數(shù)部分,小數(shù)部分被丟棄了
            TD=(TL%16)*10/16;    //計算溫度的小數(shù)部分,將余數(shù)乘以10再除以16取整,
                                          //這樣得到的是溫度小數(shù)部分的第一位數(shù)字(保留1位小數(shù))

                display_temp(TN);
                display1_temp(TD);
                _nop_(); _nop_();
        }
               
}

51hei圖片_20191227184425.png (57.36 KB, 下載次數(shù): 75)

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

使用道具 舉報

沙發(fā)
ID:584814 發(fā)表于 2019-12-30 17:07 | 只看該作者
              TN=TH*16+TL/16;      //實際溫度值=(TH*256+TL)/16,即:TH*16+TL/16
                                          //這樣得出的是溫度的整數(shù)部分,小數(shù)部分被丟棄了
            TD=(TL%16)*10/16;    //計算溫度的小數(shù)部分,將余數(shù)乘以10再除以16取整,
                                          //這樣得到的是溫度小數(shù)部分的第一位數(shù)字(保留1位小數(shù))
改成這個試試:
TN=TH<<=8|TL;
TN=TN*0.0625*1000+0.5;
TD=TN%10;TN=TN/10;
另外,以上程序都不會處理零下的溫度。
回復(fù)

使用道具 舉報

板凳
ID:213173 發(fā)表于 2019-12-31 11:00 | 只看該作者
樓主的程序基本沒有問題,關(guān)鍵是參考的程序MCU時鐘與樓主選用的不同導(dǎo)致時序誤差而產(chǎn)生讀取錯誤。

  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define delayNop(); {_nop_();_nop_();_nop_();_nop_();};

  6. uchar code table[]=" ERROR!!!       ";
  7. uchar code table1[]="xianzaiwendu    ";
  8. uchar code table2[]="Temp=    .  Cent";
  9. uchar code table3[10]="0123456789";

  10. sbit lcd_rs=P1^0;
  11. //sbit lcd_rw=P1^1;
  12. sbit lcd_en=P2^5;
  13. sbit DQ=P2^2;
  14. uchar num,time;

  15. void DelayUs2x(uchar t)
  16. {   
  17.         while(--t);
  18. }

  19. void delay(uint t)
  20. {
  21. unsigned char n;
  22.    while(t--)
  23.    {
  24.      for(n = 0; n<250; n++)
  25.     {
  26.       _nop_();
  27.       _nop_();
  28.      _nop_();
  29.       _nop_();
  30.     }
  31.    }
  32. }

  33. void write_com(uchar com)    //寫命令
  34. {
  35.         //lcd_rw=0;
  36.         //delay(5);
  37.         lcd_rs=0;
  38.         lcd_en=0;
  39.         _nop_();
  40.         _nop_();
  41.         P0=com;
  42.         delayNop();
  43.         lcd_en=1;  
  44.         delay(1);
  45.         lcd_en=0;
  46. }

  47. void write_date(uchar date)      //寫數(shù)據(jù)
  48. {
  49.         //lcd_rw=0;
  50.         // delay(5);
  51.         lcd_rs=1;
  52.         lcd_en=0;
  53.         _nop_();
  54.         _nop_();
  55.        
  56.         P0=date;        
  57.         delayNop();
  58.         lcd_en=1;                                                         
  59.         delay(1);
  60.         lcd_en=0;               
  61. }

  62. void init()       //初始化函數(shù)
  63. {
  64.         // dula=0;
  65.         // wela=0;
  66.         lcd_en=0;  //可以試試不加這一句看結(jié)果怎樣
  67.         write_com(0x38);
  68.         write_com(0x0c);
  69.         write_com(0x06);
  70.         write_com(0x01);
  71. }

  72. uchar init_DS18bB20()
  73. {
  74.         bit flag;
  75.         DQ=1;                                          //人為拉高
  76.         DelayUs2x(5);   //稍做延時                       //稍微延時6US;
  77.         DQ=0;                                                        //認為拉低
  78.         DelayUs2x(200); //精確延時 大于 480us 小于960us
  79.         DelayUs2x(200);
  80.         DQ=1;                                                                   //被上拉電阻拉高        (仿真里面沒有上拉,有沒有都需要人為拉高)
  81.         DelayUs2x(50); //15~60us 后 接收60-240us的存在脈沖                         // 延時60US檢測
  82.         flag=DQ;                                                                //這時又被DS18B20拉低,
  83.         DelayUs2x(25); //稍作延時返回                   //延時600US檢測時間
  84.         return flag;                     //返回0表示存在
  85. }

  86. void Write_Byte(uchar dat)                 //寫一個字節(jié),單片機向DS18B20寫命令,確定DS18B20的工作方法之類的
  87. {
  88.         unsigned char i=0;
  89.         for (i=0; i<8; i++)
  90.         {
  91.                 DQ =1;         // 先將數(shù)據(jù)線拉高
  92.                 _nop_();             //等待一個機器周期         
  93.                 DQ=0;          //將數(shù)據(jù)線從高拉低時即啟動寫時序      
  94.                 DQ=dat&0x01;   //利用與運算取出要寫的某位二進制數(shù)據(jù),
  95.                 //并將其送到數(shù)據(jù)線上等待DS18B20采樣        
  96.                 DelayUs2x(25);        
  97.                 //延時約30us,DS18B20在拉低后的約15~60us期間從數(shù)據(jù)線上采樣
  98.                 DQ=1;          //釋放數(shù)據(jù)線,也就是被上拉電阻拉高,反正就是要把這個口釋放,然后來執(zhí)行下一個命令                    
  99. //                for(time=0;time<1;time++)
  100. //                ;//延時3us,兩個寫時序間至少需要1us的恢復(fù)期
  101.                 dat>>=1;       //將dat中的各二進制位數(shù)據(jù)右移1位
  102.         }
  103.         DelayUs2x(25);
  104.          //稍作延時,給硬件一點反應(yīng)時間
  105. }

  106. uchar Read_Byte()
  107. {
  108.         uchar i=0;
  109.         uchar dat;//用來儲存讀出的一個字節(jié),默認為0
  110.         for(i=0;i<8;i++)
  111.         {
  112.                 DQ=1;
  113.                 _nop_();
  114.                 DQ=0;        //讀命令一定得是低電平
  115.                 dat>>=1;   //讀取數(shù)據(jù)是從高位開始讀,dat默認是0,也就是0000 0000,
  116.                 //  這是下標(biāo)是指向最高位的,所以得先右移一位讓出一個位置
  117.                 _nop_();        //需要>1US;
  118.                 DQ=1;                //又被上拉電阻拉高
  119. //                for(time=0;time<2;time++);
  120.                 if(DQ==1)                   //由DQ發(fā)送的信號來決定,發(fā)送的是高電平還是低電平
  121.                 dat|=0x80;           //高電平就或0x80,1000 0000
  122.                 else
  123.                 dat|=0x00;         //低電平就或,0x00
  124.                 DelayUs2x(25);//延時10US左右,因為需要在15US內(nèi)完成讀取
  125.         }                                 
  126.         return dat;
  127. }

  128. void Readyread()//做好讀溫度準(zhǔn)備。。。。可以加在主函數(shù)里面,但是分出來比較清晰明了
  129. {
  130.         init_DS18bB20();
  131.         Write_Byte(0xcc);        //跳過讀序號
  132.         Write_Byte(0x44);   //啟動溫度轉(zhuǎn)換
  133.         for(time=0;time<100;time++);
  134.         init_DS18bB20();           //再初始化一下
  135.         Write_Byte(0xcc);  //跳過讀序號
  136.         Write_Byte(0xbe);  //都溫度寄存器,前兩個分別是溫度的,低,高位
  137. }

  138. void display()                                                //顯示第一行說明
  139. {
  140.         write_com(0x80);
  141.         for(num=0;num<16;num++)
  142.         {
  143.                 write_date(table[num]);
  144.                 //        delay(1);
  145.         }  
  146.         while(1);
  147. }

  148. void display1()                                        //顯示第二行說明
  149. {
  150.         write_com(0x80);
  151.         for(num=0;num<16;num++)
  152.         {
  153.                 write_date(table1[num]);
  154.                 //        delay(1);
  155.         }
  156. }

  157. void display2()
  158. {
  159.         write_com(0x80+0x40);
  160.         for(num=0;num<16;num++)
  161.         {
  162.                 write_date(table2[num]);
  163.                 //delay(1);
  164.         }
  165. }
  166.                                                 
  167. void display_temp(uchar x)          //顯示溫度整數(shù)部分
  168. {
  169.         uchar bai,shi,ge;
  170.         bai=x/100;
  171.         shi=(x%100)/10;
  172.         ge=x%10;
  173.         write_com(0x80+0x46);
  174.         write_date(table3[bai]);
  175.         write_date(table3[shi]);
  176.         write_date(table3[ge]);
  177. }

  178. void display1_temp(uchar x)          //顯示溫度小數(shù)部分
  179. {
  180.         write_com(0x80+0x4a);
  181.         write_date(table3[x]);
  182. }
  183. void main()
  184. {
  185.         uchar TL;//儲存暫存器的溫度最高位
  186.         uchar TH;//儲存暫存器的溫度最低位
  187.         uchar TN; //儲存溫度整數(shù)部分
  188.         uchar TD; //儲存溫度小數(shù)部分
  189.         init();
  190.         if(init_DS18bB20()==1)
  191.         display();
  192.         display1();
  193.         display2();
  194.         while(1)
  195.         {
  196.                 Readyread();
  197.                 TL=Read_Byte();
  198.                 TH=Read_Byte();
  199.                 TN=TH*16+TL/16;      //實際溫度值=(TH*256+TL)/16,即:TH*16+TL/16
  200.                 //這樣得出的是溫度的整數(shù)部分,小數(shù)部分被丟棄了
  201.                 TD=(TL%16)*10/16;    //計算溫度的小數(shù)部分,將余數(shù)乘以10再除以16取整,
  202.                 //這樣得到的是溫度小數(shù)部分的第一位數(shù)字(保留1位小數(shù))
  203.                
  204.                 display_temp(TN);
  205.                 display1_temp(TD);
  206.                 _nop_(); _nop_();
  207.         }       
  208. }
復(fù)制代碼



回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产精品九九视频 | 日韩精品影院 | 精品视频免费 | 日韩一级| 国产一级片 | 国产性生活一级片 | 精品自拍视频在线观看 | 久久夜视频 | 91私密视频 | 成人a在线 | 精品一区二区三区在线观看 | 天天干天天操天天看 | 欧美午夜精品理论片a级按摩 | 毛片视频免费观看 | 成人影院在线观看 | 人人叉| 少妇一区二区三区 | 性高湖久久久久久久久 | 国产日韩欧美另类 | 欧美午夜一区二区三区免费大片 | 国产99久久 | 成人免费视频网站在线看 | 欧美性受xxxx白人性爽 | 国产精品网址 | www亚洲一区 | 国产精品欧美精品 | 日韩中文字幕在线视频观看 | 欧美精品在线免费 | 国产丝袜一区二区三区免费视频 | 国产精品久久久久久久久免费相片 | 久久久久一区二区三区 | 久久国产秒 | 日日夜夜91 | 天天操天天操 | 中文在线视频 | 国产激情免费视频 | 国产日韩精品视频 | 在线中文一区 | 久草在线影 | 日韩一区在线视频 | 中文字幕 亚洲一区 |