为什么DS18B20在LCD12864上显示,温度一直是0°C,求大佬们帮忙看看,谢谢了
单片机源程序如下:
#include "DS18B20.h"
#include<intrins.h>
uchar flag_temper = 0;
//****************************************************
//DS18B20延时函数
//****************************************************
void DS18B20_Delay(uint n )
{
uint i;
for(i = 0 ; i < n ; i++ );
}
//****************************************************
//DS18B20写1字节
//****************************************************
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字节
//****************************************************
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;
}
//**********************************************************
//读取温度函数,返回温度的绝对值,并标注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); //温度转换指令
if( DS18B20_Init() == 0 ) //初始化
{
DS18B20_Write_Byte(0xcc); //忽略ROM指令
DS18B20_Write_Byte(0xbe); //读暂存器指令
a = DS18B20_Read_Byte(); //读取到的第一个字节为温度LSB
b = DS18B20_Read_Byte(); //读取到的第一个字节为温度MSB
temp = b; //先把高八位有效数据赋于temp
temp <<= 8; //把以上8位数据从temp低八位移到高八位
temp = temp|a; //两字节合成一个整型变量
if(temp>0xfff)
{
flag_temper=1; //温度为负数
temp=(~temp)+1;
}
else
{
flag_temper=0; //温度为正或者0
}
tt = temp*0.0625; //得到真实十进制温度值
//因为DS18B20可以精确到0.0625度
//所以读回数据的最低位代表的是0.0625度
temp = tt*100; //放大百倍
//这样做的目的将小数点也转换为可显示数字
}
}
return temp;
}
#include"lcd12864.h"
/*******************************************************************************
* 函 数 名 : LCD12864_Delay1ms
* 函数功能 : 延时1MS
* 输 入 : c
* 输 出 : 无
*******************************************************************************/
void LCD12864_Delay1ms(uint c)
{
uint j,k;
for(j=c; j>0; j--)
for(k=114; k>0; k--);
}
/*******************************************************************************
* 函 数 名 : LCD12864_Busy
* 函数功能 : 检测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;
}
/*******************************************************************************
* 函 数 名 : LCD12864_WriteCmd
* 函数功能 : 写命令
* 输 入 : 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; //放置数据
LCD12864_EN = 1; //写时序
LCD12864_Delay1ms(5);
LCD12864_EN = 0;
}
/*******************************************************************************
* 函 数 名 : LCD12864_WriteData
* 函数功能 : 写数据
* 输 入 : 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; //选择数据
LCD12864_RW = 0; //选择写入
LCD12864_EN = 0; //初始化使能端
LCD12864_DATAPORT = dat; //放置数据
LCD12864_EN = 1; //写时序
LCD12864_Delay1ms(5);
LCD12864_EN = 0;
}
/*******************************************************************************
* 函 数 名 : LCD12864_ReadData
* 函数功能 : 读取数据
* 输 入 : 无
* 输 出 : 读取到的8位数据
*******************************************************************************/
#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
/*******************************************************************************
* 函 数 名 : LCD12864_Init
* 函数功能 : 初始化LCD12864
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void LCD12864_Init()
{
LCD12864_PSB = 1; //选择并行输入
LCD12864_RST = 1; //复位
LCD12864_WriteCmd(0x30); //选择基本指令操作
LCD12864_WriteCmd(0x0c); //显示开,关光标
LCD12864_WriteCmd(0x01); //清除LCD12864的显示内容
}
/*******************************************************************************
* 函 数 名 : LCD12864_ClearScreen
* 函数功能 : 在画图模式下,LCD12864的01H命令不能清屏,所以要自己写一个清
* * 屏函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
#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位,每位写入两个字节的的数据,也
{ //就写入32次以为当写入两个字节之后横坐标会自
LCD12864_WriteData(0xFF); //动加1,所以就不用再次写入地址了。
}
}
LCD12864_WriteCmd(0x36); //0x36扩展指令里面打开绘图显示
LCD12864_WriteCmd(0x30); //恢复基本指令集
}
#endif
/*******************************************************************************
* 函 数 名 : LCD12864_SetWindow
* 函数功能 : 设置在基本指令模式下设置显示坐标。注意:x是设置行,y是设置列
* 输 入 : 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);
}
|