51单片机 c语言 lcd1602+ds18b20 精确到小数点后1位 完美程序

#include
#include
#define uchar unsigned char
#define uint unsigned int

#define lcd_date P0 //lcd1602数据口

sbit rs=P2^0; //lcd1602控制端口定义
sbit en=P2^1; //lcd1602控制端口定义
sbit DQ=P2^3; //DS18B20数据传输线口

bit tflag;
uchar temperature; //温度值
uint tvalue;

uchar data disdata[4];
//******************************************************************
void delayms(uint ms)
{
uchar i;
while(ms--)
{
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
//******************************************************************
/*
bit lcd_bz() //忙信号,不是0就是1,所以用bit
{
lcd_date=0xff;

rs=0;
en=1;
en=1;
_nop_();
_nop_();
_nop_();
while(lcd_date&0x80); //检测忙信号
en=0;
}
*/
//******************************************************************
void lcd_wcmd(uchar cmd)
{
//while(lcd_bz()); //根据需要检测忙???????
delayms(1);
rs=0;
en=0;
lcd_date=cmd;
en=1; //若晶振速度太高可以在这后加小的延时
_nop_();
_nop_();
_nop_();
en=0;
}
//******************************************************************
void lcd_wdat(uchar dat)
{
//while(lcd_bz()); //根据需要检测忙???????
delayms(1);
rs=1;
en=0;
lcd_date=dat;
en=1; //若晶振速度太高可以在这后加小的延时
_nop_();
_nop_();
_nop_();
en=0;
}
//******************************************************************
void lcd_pos(uchar pos) //设置光标位置函数
{
lcd_wcmd(pos|0x80);
}
//******************************************************************
void writer_d(uchar *u) //写数据串//
{
while(*u)
lcd_wdat(*u++);
}
//******************************************************************
void lcd_init()
{
lcd_wcmd(0x38); //三次显示模式设置,不检测忙信号
delayms(1);
lcd_wcmd(0x38);
delayms(1);
lcd_wcmd(0x38);
delayms(1);
lcd_wcmd(0x38); //显示模式设置,开始要求每次检测忙信号
delayms(1);
lcd_wcmd(0x08); //关闭显示
delayms(1);
lcd_wcmd(0x01); //显示清屏
delayms(1);
lcd_wcmd(0x06); // 显示光标移动设置
delayms(1);
lcd_wcmd(0x0C); // 显示开及光标设置
delayms(1);
}

//******************************************************************





///////////////////////////////DS18B20温度传感器////////////////////////////////////
void delay(uint k) //DS18B20延时子程序
{
uint n;
n=0;
while(nn++;
return;
}
//******************************************************************
Init_DS18B20() //DS18B20初始化子程序
{
uchar x=0;
DQ=1; //DQ先置高
delay(8); //延时
DQ=

0; //发送复位脉冲
delay(85); //延时(>480ms)
DQ=1; //拉高数据线
delay(14); //等待(15~60ms)
}
//******************************************************************
ReadOneChar() //向DS18B20读一字节数据
{
uchar i=0;
uchar dat=0;
for (i=8;i>0;i--)
{
DQ=1;
delay(1);
DQ=0;
dat>>=1;
DQ=1;
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
}
//******************************************************************
WriteOneChar(uchar dat) //向DS18B20写一字节数据
{
uchar i=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
delay(4);
}
//******************************************************************
uchar ReadTemp()
{

uchar tempL=0; //临时变量低位
uchar tempH=0; //临时变量高位
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换

delay(125); //又是他妈的时序???????this message is wery important

Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度

delay(200);

tempL=ReadOneChar(); //读取温度值低位
tempH=ReadOneChar(); //读取温度值高位
temperature=((tempH*256)+tempL)*0.0625*10;

return(temperature);
}


//******************************************************************
void display2() //温度数据转换成液晶字符显示
{
uchar flagdat;

ReadTemp();

disdata[0]=temperature/1000+0x30;//百位数
disdata[1]=temperature%1000/100+0x30;//十位数
disdata[2]=temperature%100/10+0x30;//个位数
disdata[3]=temperature%10+0x30;//小数位

if(tflag==0)
flagdat=0x20;//正温度不显示符号
else
flagdat=0x2d;//负温度显示负号:-

if(disdata[0]=='0')
{
disdata[0]=' ';//如果百位为0,不显示
if(disdata[1]=='0')
{
disdata[1]=' ';//如果百位为0,十位为0也不显示
}
}

lcd_pos(0x46);
lcd_wdat(flagdat);//显示符号位
lcd_wdat(disdata[0]);//显示百位
lcd_wdat(disdata[1]);//显示十位
lcd_wdat(disdata[2]);//显示个位
lcd_wdat(0x2e);//显示小数点
lcd_wdat(disdata[3]);//显示小数位
lcd_wdat(0xdf); //显示℃上的小圆圈
writer_d("C");
}


//******************************************************************
void display1()
{
lcd_pos(0x01);
writer_d("weather:");
lcd_pos(0x41);
writer_d("Temp:");
}
//******************************************************************
void main()
{
Init_DS18B20();
lcd_init();
while(1)
{
display1();
display2(); //温度数据转换成液晶字符

}
}

相关文档
最新文档