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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

[求助]ds18b20數字溫度計測得溫度時對時錯

[復制鏈接]
跳轉到指定樓層
樓主
ID:34421 發表于 2012-4-24 14:31 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

大家好!我自己動手做了一個數字溫度計。用的是STC12C2052AD單片機,而溫度傳感器用的是DS18B20,12M晶振,用C語言寫(移植)的程序,但是現在溫度可以測出來,只是顯示有時是對的,有是錯的。規律是:顯示正確溫度2-3秒,跳成850約一秒,然后又顯示正確溫度。對這個現象,我真是百思不得其解,如果是時序的問題,那為什么可以測得正確的溫度?

 

還有,資料上說STC12系列的單片機是不分頻的,那是不是說比如我用12M的晶振,那么執行一條指令的時間不再是1us,而是1/12  us?

 

 

DS18B20是數字傳感器,讀出的是一個16bit的數據,前5bit表示符號,中間八位表示溫度的整數部分,我是把中間8位取出來,然后用分離出百、十、個位,送到數碼管顯示,剛開始用定時器中斷掃描數碼管,但因這個傳感器對時序要求很嚴格,便改用了軟件延時,可是用定時器與用軟件延時效果是一樣的都是對錯對錯循還。以下是我的程序,請論壇高手多多指點,在下感激不盡!

 

附件是原理圖。

(程序可以顯示正確的溫度,只是會跳動)

 

 

 

#include <reg2051.h>
#include<intrins.h>

#define  uchar unsigned char
#define  uint  unsigned int

 

void ow_reset(void);
void delay(uint t);
void write_byte(uchar val);
uint read_temp();
uchar read_byte(void);
work_temp(uint tem);
void chuli(uchar wd); 
void delayms(uint ms);        
void displays();

 

uchar wei=0;
uint temp=0;
uchar wendu=0;
uchar b,s,g,x;          //百位,十位,個位,小數
sbit d4=P3^2;         //位選信號端
sbit d3=P3^4;
sbit d2=P3^3;
sbit d1=P3^5;

 

sbit DQ=P3^7;    //接傳感 器

uchar code disdu[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};                            //段選列表
//共陽LED段碼表        "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9" "不亮" "-" 
uchar data temp_data[2]={0x00,0x00};             //讀出溫度暫放

uchar code ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};                   //小數部分直接查表


void main()
{
 ow_reset();
 write_byte(0xcc);             //Skip ROM
 write_byte(0x44);           //發轉換命令 
            
 while(1)
     {
       work_temp(read_temp());
  
       displays();   
 
 }
 

}


void ow_reset(void)      //復位
{
char presence=1;
while(presence)
{
  while(presence)
   {
    DQ=1;_nop_();_nop_();//從高拉倒低
 DQ=0;                                       
 delay(50);           //550 us
 DQ=1;                                        
 delay(6);            //66 us
 presence=DQ;  //presence=0 復位成功,繼續下一步
 } 
   delay(45);            //延時500 us
   presence=~DQ;         
}
DQ=1;                  //拉高電平      

}

 

 

/****************DS18B20寫命令函數************************/
//向1-WIRE 總線上寫1個字節
void write_byte(uchar val)
{ 
  uchar i;
  for(i=8;i>0;i--)
  {
   DQ=1;_nop_();_nop_();                 //從高拉倒低
   DQ=0;_nop_();_nop_();_nop_();_nop_();  //5 us
   DQ=val&0x01;                           //最低位移出
   delay(6);                              //66 us
   val=val/2;                             //右移1位
   }
   DQ=1;
   delay(1);
}


/****************DS18B20讀1字節函數************************/
//從總線上取1個字節
uchar read_byte(void)
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
  DQ=1;_nop_();_nop_();
  value>>=1;
  DQ=0;_nop_();_nop_();_nop_();_nop_();        //4 us
  DQ=1;_nop_();_nop_();_nop_();_nop_();        //4 us
  if(DQ)value|=0x80;
  delay(6);                                     //66 us
}
DQ=1;
return(value);
}

 

uint read_temp()
{
  ow_reset();                  //總線復位
  delay(200);
  write_byte(0xcc);            //發命令
  write_byte(0x44);            //發轉換命令
  ow_reset(); 
  delay(1);
  write_byte(0xcc);            //發命令
  write_byte(0xbe);
  temp_data[0]=read_byte();    //讀溫度值的第字節
  delay(3);
  temp_data[1]=read_byte();    //讀溫度值的高字節
  temp=temp_data[1];
  temp<<=8;                                               
  temp=temp|temp_data[0];      // 兩字節合成一個整型變量。
  return(temp);                 //返回溫度值
}

 


/****************溫度數據處理函數************************/

//二進制高字節的低半字節和低字節的高半字節組成一字節,這個
//字節的二進制轉換為十進制后,就是溫度值的百、十、個位值,而剩
//下的低字節的低半字節轉化成十進制后,就是溫度值的小數部分

/********************************************************/
work_temp(uint tem)
{
 uchar n=0;
 if(tem>6348)                        // 溫度值正負判斷
 {
  tem=65536-tem;
  n=1;
 }
 x=tem&0x0f;            // 取小數部分的值     

 wendu=tem>>4;             // 取中間八位,即整數部分的值
 chuli(wendu);   
 if(n)
  b=0x0b;      //負溫度時最高位顯示"-"
 
}


void delay(uint t)
{     t=t*12;                                //stc12系列單片機不分頻,乘以8-12時,延時約10us
  for (;t>0;t--);
}

 

 

void delayms(uint ms)        
{
 ms=120*2*ms;     //取這個參數顯示比較穩定(數碼管不閃爍,也有較高亮度)
 for(;ms>0;ms--)
 ;
}

 

 

void displays()                      //顯示溫度
{
 P1=disdu[ditab[x]];
 d1=0;
 delayms(5);
 d1=1;

 

 P1=disdu[g];

 P1^7=0;      //點亮小數點
 d2=0;
 delayms(5);
 d2=1;

 

 P1=disdu;
 d3=0;
 delayms(5);
 d3=1;

 

 P1=disdu;
 d4=0;
 delayms(5);
 d4=1;
} 

 

 


void chuli(uchar wd) 
{
 b=wd/100;
 s=wd%100/10;
 g=wd%100%10;
 if(b==0)
  b=10;
 if(s==0)
  s=10;
}

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

使用道具 舉報

沙發
ID:1 發表于 2012-4-24 14:38 | 只看該作者

也不是是1/12  us ,實際的速度你得把c語言反匯編以后再對照stc的指令周期表 才知道了.

回復

使用道具 舉報

板凳
ID:34421 發表于 2012-4-24 14:51 | 只看該作者
嗯 ,但為什么測得的溫度會跳動呢?而且是一半是對的,一半是錯的。我調節過那個讀取溫度的頻率,但都會出同樣 的錯。硬件電路是在覆銅板上用刀刻的。現在才知道做好硬件才是個開始,程序研究好些日子了,昨天調試到可以顯溫度,一直找不到跳 動 的原因,我試圖將讀出的高字節和低字節分別送出顯示,都有跳 動,也就是說,我從傳感器里讀出的數就是一個跳動的。有沒有可能是出溫度的那一部分出了錯,使讀的數錯位了呢?還是它正在轉換又接到讀的命令,而沒有對1820讀忙狀態呢?
回復

使用道具 舉報

地板
ID:39301 發表于 2012-4-27 09:54 | 只看該作者
頂一下,學習一下!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产网址 | 91久久国产综合久久 | 日本特黄a级高清免费大片 国产精品久久性 | 亚欧洲精品在线视频免费观看 | 视频一区在线观看 | 午夜视频在线播放 | a免费视频 | 久久久久国产一区二区三区不卡 | 久久88| 91在线精品秘密一区二区 | 国产精品美女久久久 | 国产精品国产馆在线真实露脸 | 亚洲综合精品 | 成人亚洲精品久久久久软件 | 日韩欧美在| 欧美视频三区 | 欧美精品二区三区 | a在线视频观看 | 国产99小视频 | 日韩免费视频一区二区 | 国产色网站 | 午夜电影网 | 久久久久久久夜 | 亚洲+变态+欧美+另类+精品 | 波多野结衣先锋影音 | 中文字幕亚洲区一区二 | 91精品久久久久久久久99蜜臂 | 亚洲综合精品 | 久久国产精品久久久久久 | 欧美久久视频 | 偷拍第一页 | www.99热 | 亚洲欧美在线一区 | 81精品国产乱码久久久久久 | 东京av男人的天堂 | www.成人久久 | 国产一区二区三区免费 | 久久精品国产久精国产 | 中文字字幕一区二区三区四区五区 | 久久精品欧美一区二区三区不卡 | 亚洲视频在线一区 |