標題:
為什么單片機DS18B20程序一直顯示0°C
[打印本頁]
作者:
qzuserll
時間:
2022-3-28 20:21
標題:
為什么單片機DS18B20程序一直顯示0°C
為什么DS18B20在LCD12864上顯示,溫度一直是0°C,求大佬們幫忙看看,謝謝了
單片機源程序如下:
#include "DS18B20.h"
#include<intrins.h>
uchar flag_temper = 0;
//****************************************************
//DS18B20延時函數(shù)
//****************************************************
void DS18B20_Delay(uint n )
{
uint i;
for(i = 0 ; i < n ; i++ );
}
//****************************************************
//DS18B20寫1字節(jié)
//****************************************************
void DS18B20_Write_Byte( uchar dat)
{
uchar i;
for( i = 0 ; i < 8 ; i++ )
{
DS18B20_DQ = 0;
_nop_(); //延時>1us
_nop_();
DS18B20_DQ = dat&0x01; //先寫低位
dat >>= 1;
DS18B20_Delay(6); //延時60~120us
DS18B20_DQ = 1; //釋放總線
_nop_(); //延時>1us
_nop_();
}
}
//****************************************************
//DS18B20讀1字節(jié)
//****************************************************
uchar DS18B20_Read_Byte( )
{
uchar dat,i;
for( i = 0 ; i < 8 ; i++ )
{
DS18B20_DQ = 0;
_nop_(); //延時>1us
_nop_();
DS18B20_DQ = 1; //釋放總線
_nop_(); //延時>1us
_nop_();
dat >>= 1;
if( DS18B20_DQ == 1)
{
dat |= 0X80;
}
else
{
dat &= 0x7f;
}
DS18B20_Delay(6); //延時60~120us
}
return dat;
}
//****************************************************
//DS18B20初始化
//****************************************************
bit DS18B20_Init()
{
bit Flag_exist = 1;
DS18B20_DQ = 1; //釋放總線
_nop_(); //延時>1us
_nop_();
DS18B20_DQ = 0;
DS18B20_Delay(50); //延時480~960us
DS18B20_DQ = 1; //釋放總線
DS18B20_Delay(3); //延時15~60us
Flag_exist = DS18B20_DQ;
DS18B20_Delay(10); //延時60~240us
DS18B20_DQ = 1; //釋放總線
return Flag_exist;
}
//**********************************************************
//讀取溫度函數(shù),返回溫度的絕對值,并標注flag_temper,flag_temper=1表示負,flag_temper=0表示正
//**********************************************************
uint Get_temp(void) //讀取溫度值
{
float tt;
uchar a,b;
uint temp;
if( DS18B20_Init() == 0 ) //初始化
{
DS18B20_Write_Byte(0xcc); //忽略ROM指令
DS18B20_Write_Byte(0x44); //溫度轉(zhuǎn)換指令
if( DS18B20_Init() == 0 ) //初始化
{
DS18B20_Write_Byte(0xcc); //忽略ROM指令
DS18B20_Write_Byte(0xbe); //讀暫存器指令
a = DS18B20_Read_Byte(); //讀取到的第一個字節(jié)為溫度LSB
b = DS18B20_Read_Byte(); //讀取到的第一個字節(jié)為溫度MSB
temp = b; //先把高八位有效數(shù)據(jù)賦于temp
temp <<= 8; //把以上8位數(shù)據(jù)從temp低八位移到高八位
temp = temp|a; //兩字節(jié)合成一個整型變量
if(temp>0xfff)
{
flag_temper=1; //溫度為負數(shù)
temp=(~temp)+1;
}
else
{
flag_temper=0; //溫度為正或者0
}
tt = temp*0.0625; //得到真實十進制溫度值
//因為DS18B20可以精確到0.0625度
//所以讀回數(shù)據(jù)的最低位代表的是0.0625度
temp = tt*100; //放大百倍
//這樣做的目的將小數(shù)點也轉(zhuǎn)換為可顯示數(shù)字
}
}
return temp;
}
#include"lcd12864.h"
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_Delay1ms
* 函數(shù)功能 : 延時1MS
* 輸 入 : c
* 輸 出 : 無
*******************************************************************************/
void LCD12864_Delay1ms(uint c)
{
uint j,k;
for(j=c; j>0; j--)
for(k=114; k>0; k--);
}
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_Busy
* 函數(shù)功能 : 檢測LCD是否忙
* 輸 入 : 無
* 輸 出 : 1或0(1表示不忙,0表示忙)
*******************************************************************************/
uchar LCD12864_Busy(void)
{
uchar i = 0;
LCD12864_RS = 0; //選擇命令
LCD12864_RW = 1; //選擇讀取
LCD12864_EN = 1;
LCD12864_Delay1ms(1);
while((LCD12864_DATAPORT & 0x80) == 0x80) //檢測讀取到的值
{
i++;
if(i > 100)
{
LCD12864_EN = 0;
return 0; //超過等待時間返回0表示失敗
}
}
LCD12864_EN = 0;
return 1;
}
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_WriteCmd
* 函數(shù)功能 : 寫命令
* 輸 入 : cmd
* 輸 出 : 無
*******************************************************************************/
void LCD12864_WriteCmd(uchar cmd)
{
uchar i;
i = 0;
while( LCD12864_Busy() == 0)
{
LCD12864_Delay1ms(1);
i++;
if( i>100)
{
return; //超過等待退出
}
}
LCD12864_RS = 0; //選擇命令
LCD12864_RW = 0; //選擇寫入
LCD12864_EN = 0; //初始化使能端
LCD12864_DATAPORT = cmd; //放置數(shù)據(jù)
LCD12864_EN = 1; //寫時序
LCD12864_Delay1ms(5);
LCD12864_EN = 0;
}
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_WriteData
* 函數(shù)功能 : 寫數(shù)據(jù)
* 輸 入 : dat
* 輸 出 : 無
*******************************************************************************/
void LCD12864_WriteData(uchar dat)
{
uchar i;
i = 0;
while( LCD12864_Busy() == 0)
{
LCD12864_Delay1ms(1);
i++;
if( i>100)
{
return; //超過等待退出
}
}
LCD12864_RS = 1; //選擇數(shù)據(jù)
LCD12864_RW = 0; //選擇寫入
LCD12864_EN = 0; //初始化使能端
LCD12864_DATAPORT = dat; //放置數(shù)據(jù)
LCD12864_EN = 1; //寫時序
LCD12864_Delay1ms(5);
LCD12864_EN = 0;
}
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_ReadData
* 函數(shù)功能 : 讀取數(shù)據(jù)
* 輸 入 : 無
* 輸 出 : 讀取到的8位數(shù)據(jù)
*******************************************************************************/
#ifdef LCD12864_PICTURE
uchar LCD12864_ReadData(void)
{
uchar i, readValue;
i = 0;
while( LCD12864_Busy() == 0)
{
LCD12864_Delay1ms(1);
i++;
if( i>100)
{
return 0; //超過等待退出
}
}
LCD12864_RS = 1; //選擇命令
LCD12864_RW = 1;
LCD12864_EN = 0;
LCD12864_Delay1ms(1); //等待
LCD12864_EN = 1;
LCD12864_Delay1ms(1);
readValue = LCD12864_DATAPORT;
LCD12864_EN = 0;
return readValue;
}
#endif
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_Init
* 函數(shù)功能 : 初始化LCD12864
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void LCD12864_Init()
{
LCD12864_PSB = 1; //選擇并行輸入
LCD12864_RST = 1; //復(fù)位
LCD12864_WriteCmd(0x30); //選擇基本指令操作
LCD12864_WriteCmd(0x0c); //顯示開,關(guān)光標
LCD12864_WriteCmd(0x01); //清除LCD12864的顯示內(nèi)容
}
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_ClearScreen
* 函數(shù)功能 : 在畫圖模式下,LCD12864的01H命令不能清屏,所以要自己寫一個清
* * 屏函數(shù)
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
#ifdef LCD12864_PICTURE
void LCD12864_ClearScreen(void)
{
uchar i,j;
LCD12864_WriteCmd(0x34); //開啟拓展指令集
for(i=0;i<32;i++) //因為LCD有縱坐標32格所以寫三十二次
{
LCD12864_WriteCmd(0x80+i); //先寫入縱坐標Y的值
LCD12864_WriteCmd(0x80); //再寫入橫坐標X的值
for(j=0;j<32;j++) //橫坐標有16位,每位寫入兩個字節(jié)的的數(shù)據(jù),也
{ //就寫入32次以為當寫入兩個字節(jié)之后橫坐標會自
LCD12864_WriteData(0xFF); //動加1,所以就不用再次寫入地址了。
}
}
LCD12864_WriteCmd(0x36); //0x36擴展指令里面打開繪圖顯示
LCD12864_WriteCmd(0x30); //恢復(fù)基本指令集
}
#endif
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_SetWindow
* 函數(shù)功能 : 設(shè)置在基本指令模式下設(shè)置顯示坐標。注意:x是設(shè)置行,y是設(shè)置列
* 輸 入 : x, y
* 輸 出 : 無
*******************************************************************************/
void LCD12864_SetWindow(uchar x, uchar y)
{
uchar pos;
if(x == 0) // 第一行的地址是80H
{
x = 0x80;
}
else if(x == 1) //第二行的地址是90H
{
x = 0x90;
}
else if(x == 2) //第三行的地址是88H
{
x = 0x88;
}
else if(x == 3)
{
x = 0x98;
}
pos = x + y;
LCD12864_WriteCmd(pos);
}
作者:
man1234567
時間:
2022-3-29 08:18
多是網(wǎng)上抄的程序應(yīng)該沒問題,但并不表示運行沒問題。
不同的單片機運行速度不一樣,所以延時的時長也有區(qū)別,需要按實調(diào)整。
回到問題:一直顯示0極大可能是讀不出數(shù)據(jù),一般程序與單片機協(xié)調(diào)問題居多,不排除硬件接錯。
作者:
lkc8210
時間:
2022-3-29 16:34
一直顯示0可能是初始化不成功
Flag_exist保持為1
同意沙發(fā)的說法
請檢查DS18B20的各個延時時間
作者:
TEC
時間:
2022-3-30 10:04
顯示值是0,是沒把ds18b20里的數(shù)據(jù)讀出來,把main函數(shù)貼出來,有時是延時不夠造成的。
作者:
Leokex
時間:
2022-3-30 14:45
問題可能:1.程序問題(大多數(shù)網(wǎng)上程序復(fù)制下了是要微調(diào)的),這就要求你做到移植而非復(fù)制;2.延時問題,一些采樣器件對延時是有要求的,要確保延時是正確的,可以看一下官方手冊;3.硬件電路問題,剛開始經(jīng)常會出現(xiàn)仿真能用,但是實物有問題。這時候不要慌張,一點一點排除錯誤,可以測通斷,測電壓,檢查一下PCB畫原理圖或是連線,通過不斷的縮小范圍,找到問題所在。這個回答是一般錯誤檢查的步驟,希望對你有用。
作者:
xiaxiao1127
時間:
2022-3-30 16:38
用PROTEUS搭個電路仿真吧這樣你能快速找到問題。
作者:
小象
時間:
2022-4-8 18:25
在復(fù)位成功后加一個亮燈啊或聲音提示啊,看看是不是復(fù)位成為了。。然后再查讀寫的步驟和延時,要是18B20接線長一些的話,對時序更嚴格。。
作者:
余英杰
時間:
2022-4-9 21:49
ds18b20就是單總線協(xié)議,極有可能是時序不對導(dǎo)致數(shù)據(jù)就沒讀好,你可以先自己設(shè)一個數(shù)據(jù),看看能不能顯示,要是可以顯示,那就是讀的問題,建議看看數(shù)據(jù)手冊對應(yīng)時序,先調(diào)一個簡單的復(fù)位,看看ds18b20有沒有響應(yīng)工作
作者:
univers
時間:
2022-4-9 22:28
網(wǎng)上抄的程序也要自己重新整理過,你這樣肯定是亂七八招的。單片機也不知什么型號,時序頻率等等。。。。。。。。。!
作者:
a110ddwy
時間:
2022-4-10 09:57
移植要考慮目標的硬件環(huán)境和源程序的硬件環(huán)境的區(qū)別。
作者:
天ノ憶
時間:
2022-4-10 14:30
用示波器測一下波形不就什么都知道了
作者:
1314520jieber
時間:
2022-4-10 15:27
無外乎時序不對
作者:
1314520jieber
時間:
2022-4-10 15:28
用邏輯分析儀測一下就曉得了
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1