找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機數(shù)碼管顯示ds18b20溫度值不正常

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:481844 發(fā)表于 2019-3-20 08:31 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 心靈的塵埃 于 2019-3-20 08:34 編輯

#include <reg52.h>
#include <intrins.h>


#define uchar unsigned char
#define uint unsigned int
sbit du26=P2^6;//數(shù)碼管段選
sbit we27=P2^7;//數(shù)碼管位選
sbit DS=P2^2;//溫度傳感器
uchar sum;//將溫度值送到數(shù)碼管顯示
uchar code led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0~9數(shù)碼管段表
uchar code smgwei[]={0xfe,0xfd,0xfb};       //1~3數(shù)碼管位表


void we(uchar z) //位選
{
        P0=z;
        we27=1;
        we27=0;        
}


void du(uchar z)   //段選
{         
        P0=z;
        du26=1;
        du26=0;        
}
void display(uchar z) //三個數(shù)碼管顯示
{
        static uchar wei;
        switch(wei)
        {
                case 0:we(smgwei[wei]);du(led[z/100]);break;
                case 1:we(smgwei[wei]);du(led[z%100/10]|0x80);break;
                case 2:we(smgwei[wei]);du(led[z%10]);break;
        }
        wei++;
        if(wei==3)
                wei=0;
}


void timer0int() interrupt 1 //定時器,定時5ms
{
        TH0=(65535-5000)/256;
        TL0=(65535-5000)%256;
        display(sum);         
}
void delay_us(uchar us)        //延時函數(shù)
{
         while(us--);
}


//單總線初始化時序         
bit ds_init()
{
        bit i;
        DS=1;
        _nop_();
        DS=0;
        delay_us(75);//拉低總線499.45us,總線上的溫度傳感器將會被全部復(fù)位
        DS=1;//釋放總線
        delay_us(4);//延時37.95us,等待溫度傳感器發(fā)回存在信號
        i=DS;
        delay_us(20);//延時141.95us,讀取溫度傳感器存在的時間
        DS=1;
        _nop_();
        return (i);
}
//寫一個字節(jié)
void write_byte(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {
                DS=0;
                _nop_(); //產(chǎn)生寫時序
                DS=dat&0x01;
                delay_us(10);//延時76.95us
                DS=1;//釋放總線準(zhǔn)備下一次數(shù)據(jù)的寫入
                _nop_();
                dat>>=1;
        }
}
//讀一個字節(jié)
uchar read_byte()
{
        uchar i,j,dat;
        for(i=0;i<8;i++)
        {
                DS=0;
                _nop_();//產(chǎn)生讀時序
                DS=1;
                _nop_();//釋放總線
                j=DS;
                delay_us(10);//76.95us
                DS=1;
                _nop_();
                dat=(j<<7)|(dat>>1);
        }
        return (dat);
}  
void main()
{        
        uint i;
        uchar L,M;
        EA=1;
        ET0=1;
        TR0=1;
        TMOD=0X01;
        TH0=(65535-5000)/256;
        TL0=(65535-5000)%256;


        
        while(1)           
        {
                ds_init();//初始化溫度傳感器
                write_byte(0xcc);//發(fā)送跳躍ROM指令
                write_byte(0x44);//發(fā)送溫度轉(zhuǎn)換指令
                ds_init();//初始化溫度傳感器
                write_byte(0xcc);//發(fā)送跳躍ROM指令
                write_byte(0xbe);//讀取溫度傳感器暫存器的值
                L=read_byte();
                M=read_byte();
                i=M;
                i<<=8;
                i|=L;          //將讀出來的數(shù)據(jù)合并存到i中
                i=i*0.625*10+0.5;
        i=sum;
                                
        } 求問題出在哪里,謝謝。!      
}


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

使用道具 舉報

沙發(fā)
ID:443783 發(fā)表于 2019-3-20 09:50 | 只看該作者
沒的圖紙 怎么幫?
回復(fù)

使用道具 舉報

板凳
ID:437981 發(fā)表于 2019-3-20 13:48 | 只看該作者
ds18b20是單總線通信,它對時序要求非常高,你可能需要檢查你的延遲
回復(fù)

使用道具 舉報

地板
ID:164602 發(fā)表于 2019-3-20 14:38 | 只看該作者
試試我的程序:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2;   
uint temp;        
uchar flag1;        
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
                        0x87,0xff,0xef};

void delay(uint count)   
{
  uint i;
  while(count)
  {
    i=200;
    while(i>0)
    i--;
    count--;
  }
}


void dsreset(void)  
{
  uint i;
  DS=0;                              
  i=103;                               
  while(i>0)i--;
  DS=1;                               
  i=4;                                       
  while(i>0)i--;

}

bit tmpreadbit(void)   
{
   uint i;
   bit dat;
   DS=0;i++;      
   DS=1;i++;i++;
   dat=DS;
   i=8;while(i>0)i--;
   return (dat);
}

uchar tmpread(void)
{
  uchar i,j,dat;
  dat=0;
  for(i=1;i<=8;i++)
  {
    j=tmpreadbit();
    dat=(j<<7)|(dat>>1);
  }
  return(dat);
}

void tmpwritebyte(uchar dat)  
{
  uint i;
  uchar j;
  bit testb;
  for(j=1;j<=8;j++)
  {
    testb=dat&0x01;
    dat=dat>>1;
    if(testb)   
    {
      DS=0;
      i++;i++;
      DS=1;
      i=8;while(i>0)i--;
    }
    else
    {
      DS=0;     
      i=8;while(i>0)i--;
      DS=1;
      i++;i++;
    }

  }
}

void tmpchange(void)
{
  dsreset();
  delay(1);
  tmpwritebyte(0xcc);
  tmpwritebyte(0x44);

}

uint tmp()            
{
  float tt;
  uchar a,b;
  dsreset();
  delay(1);
  tmpwritebyte(0xcc);
  tmpwritebyte(0xbe);
  a=tmpread();
  b=tmpread();
  temp=b;
  temp<<=8;         
  temp=temp|a;
  tt=temp*0.0625;
  temp=tt*10+0.5;
  return temp;
}

void readrom()      
{
  uchar sn1,sn2;
  dsreset();
  delay(1);
  tmpwritebyte(0x33);
  sn1=tmpread();
  sn2=tmpread();
}


void delay10ms()      
  {
    uchar a,b;
    for(a=10;a>0;a--)
      for(b=60;b>0;b--);
   }

void display(uint temp)               
{
   uchar A1,A2,A2t,A3,ser;
   ser=temp/10;
   SBUF=ser;
   A1=temp/100;
   A2t=temp%100;
   A2=A2t/10;
   A3=A2t%10;
   dula=0;
   P0=table[A1];       
   dula=1;
   dula=0;

   wela=0;
   P0=0xfe;
   wela=1;
   wela=0;
   delay(1);

   dula=0;
   P0=table1[A2];               
   dula=1;
   dula=0;

   wela=0;
   P0=0xfd;
   wela=1;
   wela=0;
   delay(1);

   P0=table[A3];       
   dula=1;
   dula=0;

   P0=0xfb;
   wela=1;
   wela=0;
   delay(1);
}


void main()
{
uchar a;
  do
  {
    tmpchange();
  

for(a=100;a>0;a--)
  {   display(tmp());
  }
  }                while(1);
}

回復(fù)

使用道具 舉報

5#
ID:491577 發(fā)表于 2019-3-20 21:24 | 只看該作者
數(shù)碼管顯示語句有問題:
                case 0:we(smgwei[wei]);du(led[z/100]);break;
                case 1:we(smgwei[wei]);du(led[z%100/10]|0x80);break;
                case 2:we(smgwei[wei]);du(led[z%10]);break;
回復(fù)

使用道具 舉報

6#
ID:213173 發(fā)表于 2019-3-20 21:49 | 只看該作者
改為6位數(shù)碼管顯示-55~128度,保留2位小數(shù)。

  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. /************定義端口*************/
  6. sbit du26=P2^6;//數(shù)碼管段選
  7. sbit we27=P2^7;//數(shù)碼管位選
  8. sbit DS=P2^2;//溫度傳感器
  9. /************定義全局變量*************/
  10. uchar code led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0~9數(shù)碼管段表
  11. uchar code smgwei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};       //1~6數(shù)碼管位表
  12. uchar TempData[6]; //存儲顯示值的全局變量
  13. bit ReadTempFlag;        //讀時間標(biāo)志

  14. /*------------------------------------------------
  15.                   函數(shù)聲明
  16. ------------------------------------------------*/
  17. void WriteOneChar(uchar dat);        //寫入DS18B20一個字節(jié)
  18. uchar ReadOneChar(void);                //讀取DS18B20一個字節(jié)
  19. uint ReadTemperature(void);        //讀取DS18B20溫度值
  20. bit Init_DS18B20(void);                        //初始化DS18B20
  21. void Display(void);                                        //數(shù)碼管顯示函數(shù)
  22. void Init_Timer0(void);                        //定時器初始化
  23. void DelayUs2x(uchar t);                //uS延時函數(shù)
  24. void DelayMs(uchar t);                        //mS延時函數(shù)
  25. void we(uchar z); //位選
  26. void du(uchar z);   //段選
  27. /*------------------------------------------------
  28.                     主函數(shù)
  29. ------------------------------------------------*/
  30. void main()
  31. {                  
  32.         uint temp;
  33.         long tempM;
  34.         bit negative;//負(fù)數(shù)標(biāo)志
  35.         uchar TempH,TempL,TempK;
  36.         Init_Timer0();
  37.         TempData[5]=0x39;                //顯示C
  38.         while(1)         //主循環(huán)
  39.         {
  40.                 if(ReadTempFlag==1)//定時標(biāo)志
  41.                 {
  42.                         ReadTempFlag=0;
  43.                         temp=ReadTemperature();//讀取溫度
  44.                         if(temp&0x8000)
  45.                         {
  46.                                 negative=1;                //負(fù)號標(biāo)志
  47.                                 temp=~temp;                //取反加1
  48.                                 temp +=1;
  49.                         }
  50.                         else negative=0;        //正數(shù)

  51.                         tempM=temp*0.0625*100;        //換算為10進制溫度值再放大100倍
  52.                         TempH=tempM/100;                                //分解出整數(shù)值       
  53.                         TempL=tempM%100;                                //分解出小數(shù)值
  54.                         TempL=(TempL+TempK)/2+0.5;//小數(shù)取兩次平均值加四舍五入
  55.                         TempK=TempL;
  56.                        
  57.                         if(negative==1)
  58.                                 TempData[0]=0x40;//顯示負(fù)號
  59.                         else if(TempH/100==0)//小于100
  60.                                 TempData[0]=0;                                                                                        //百位消隱
  61.                         else
  62.                                 TempData[0]=led[TempH/100];                         //顯示百位溫度
  63.        
  64.                         if((TempH/100==0)&&((TempH%100)/10==0))
  65.                                 TempData[1]=0;                                                                                        //十位消隱
  66.                         else
  67.                                 TempData[1]=led[(TempH%100)/10];                //顯示十位溫度
  68.                         TempData[2]=led[(TempH%100)%10]|0x80;//顯示個位溫度,帶小數(shù)點
  69.                         TempData[3]=led[TempL/10];                                //顯示溫度小數(shù)1位
  70.                         TempData[4]=led[TempL%10];                                //顯示溫度小數(shù)2位       

  71.                 }
  72.         }
  73. }
  74. void we(uchar z) //位選
  75. {
  76.         P0=z;
  77.         we27=1;
  78.         we27=0;        
  79. }
  80. void du(uchar z)   //段選
  81. {         
  82.         P0=z;
  83.         du26=1;
  84.         du26=0;
  85. }
  86. /*------------------------------------------------
  87.                                 6位動態(tài)數(shù)碼管顯示函數(shù)
  88. ------------------------------------------------*/
  89. void Display() //6個數(shù)碼管顯示
  90. {
  91.         static uchar wei;
  92.         switch(wei)
  93.         {
  94.                 case 0:we(smgwei[wei]);du(TempData[wei]);break;
  95.                 case 1:we(smgwei[wei]);du(TempData[wei]);break;
  96.                 case 2:we(smgwei[wei]);du(TempData[wei]);break;
  97.                 case 3:we(smgwei[wei]);du(TempData[wei]);break;
  98.                 case 4:we(smgwei[wei]);du(TempData[wei]);break;
  99.                 case 5:we(smgwei[wei]);du(TempData[wei]);break;
  100.         }
  101.         wei++;
  102.         wei%=6;
  103. }

  104. /*------------------------------------------------
  105.             定時器初始化子程序
  106. ------------------------------------------------*/
  107. void Init_Timer0(void)
  108. {
  109.          TMOD |= 0x01;
  110.          TH0=(65536-2000)/256;              //給定初值
  111.          TL0=(65536-2000)%256;
  112.          EA=1;            //總中斷打開
  113.          ET0=1;           //定時器中斷打開
  114.          TR0=1;           //定時器開關(guān)打開
  115. }
  116. /*------------------------------------------------
  117.                  定時器中斷子程序
  118. ------------------------------------------------*/
  119. void Timer0_isr(void) interrupt 1
  120. {
  121.         static uint num;
  122.         TH0=(65536-2000)/256;        //重新賦值 2ms
  123.         TL0=(65536-2000)%256;
  124.        
  125.         Display();       // 調(diào)用數(shù)碼管掃描
  126.         num++;
  127.         if(num>=250)        //500ms
  128.         {
  129.                 num=0;
  130.                 ReadTempFlag=1; //讀標(biāo)志位置1
  131.         }
  132. }

  133. /*------------------------------------------------
  134.          2uS延時函數(shù)
  135. ------------------------------------------------*/
  136. void DelayUs2x(uchar t)
  137. {   
  138.         while(--t);
  139. }
  140. /*------------------------------------------------
  141.         1mS延時函數(shù)
  142. ------------------------------------------------*/
  143. void DelayMs(uchar t)
  144. {
  145.         while(t--)
  146.         {
  147.                 //大致延時1mS
  148.                 DelayUs2x(245);
  149.                 DelayUs2x(245);
  150.         }
  151. }
  152. /*------------------------------------------------
  153.                     18b20初始化
  154. ------------------------------------------------*/
  155. bit Init_DS18B20(void)
  156. {
  157.         bit dat=0;
  158.         DS = 1;                    //DS復(fù)位
  159.         DelayUs2x(5);   //稍做延時
  160.         DS = 0;         //單片機將DS拉低
  161.         DelayUs2x(200); //精確延時 大于 480us 小于960us
  162.         DelayUs2x(200);
  163.         DS = 1;        //拉高總線
  164.         DelayUs2x(50); //15~60us 后 接收60-240us的存在脈沖
  165.         dat=DS;        //如果x=0則初始化成功, x=1則初始化失敗
  166.         DelayUs2x(25); //稍作延時返回
  167.         return dat;
  168. }

  169. /*------------------------------------------------
  170.                     讀取一個字節(jié)
  171. ------------------------------------------------*/
  172. uchar ReadOneChar(void)
  173. {
  174.         uchar i=0;
  175.         uchar dat = 0;
  176.         for (i=8;i>0;i--)
  177.         {
  178.                 DS = 0; // 給脈沖信號
  179.                 dat>>=1;
  180.                 DS = 1; // 給脈沖信號
  181.                 if(DS)
  182.                 dat|=0x80;
  183.                 DelayUs2x(25);
  184.         }
  185.         return(dat);
  186. }
  187. /*------------------------------------------------
  188.                     寫入一個字節(jié)
  189. ------------------------------------------------*/
  190. void WriteOneChar(uchar dat)
  191. {
  192.         uchar i=0;
  193.         for(i=8; i>0; i--)
  194.         {
  195.                 DS = 0;
  196.                 DS = dat&0x01;
  197.                 DelayUs2x(25);
  198.                 DS = 1;
  199.                 dat>>=1;
  200.         }
  201.         DelayUs2x(25);
  202. }

  203. /*------------------------------------------------
  204.                     讀取溫度
  205. ------------------------------------------------*/
  206. uint ReadTemperature(void)
  207. {
  208.         uchar a=0;
  209.         uint b=0;
  210.         uint t=0;
  211.         Init_DS18B20();
  212.         WriteOneChar(0xCC); // 跳過讀序號列號的操作
  213.         WriteOneChar(0x44); // 啟動溫度轉(zhuǎn)換
  214.         DelayMs(10);
  215.         Init_DS18B20();
  216.         WriteOneChar(0xCC); //跳過讀序號列號的操作
  217.         WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
  218.         a=ReadOneChar();   //低位
  219.         b=ReadOneChar();   //高位
  220.         b<<=8;
  221.         t=a+b;
  222.         return(t);
  223. }
復(fù)制代碼



評分

參與人數(shù) 1黑幣 +6 收起 理由
心靈的塵埃 + 6

查看全部評分

回復(fù)

使用道具 舉報

7#
ID:383721 發(fā)表于 2019-3-21 13:53 | 只看該作者
如果是實際電路的話,DS18B20溫度轉(zhuǎn)換最少要93.57ms(9位),最多要750ms(12位),之后才能讀取到正確的數(shù)據(jù),protues仿真就不需要
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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