📄 main.c
字号:
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit rs=P2^2; // 命令数据选择
sbit lcden=P2^1; //使能
sbit DQ=P2^0;//18B20数据通信线
uchar Rl,Rh;//温度低位,温度高位
uchar a,c,q,sign;//中间变量 C为温度整数部分 a为小数部分 q为正负号
uint bai,shi,ge,baifen,shifen,qianfen,wanfen;
uchar table[]={'0','1','2','3','4','5','6','7','8','9'};
//延时
void delay(uchar t)
{
uchar i,j;
for(i=t;i>0;i--)
for(j=10;j>0;j--);
}
void delayms(uchar t)
{
uchar i,j;
for(i=t;i>0;i--)
for(j=200;j>0;j--);
}
//lcd写命令
void write_com(uchar com)
{
P0=com;
rs=0;
lcden=0;
delay(10);
lcden=1;
delay(30);
lcden=0;
}
//lcd写数据
void write_date(uchar date)
{
P0=date;
rs=1;
lcden=0;
delay(10);
lcden=1;
delay(30);
lcden=0;
}
//lcd初始化
void lcdinit()
{
write_com(0x38);//显示模式5*7
delay(20);
write_com(0x08);//开显示开光标开闪烁
delay(20);
write_com(0x06);//
delay(20);
write_com(0x01);//清屏
delay(20);
write_com(0x0c);
delay(20);
write_com(0x80);
delay(10);
write_date('T');
delay(10);
write_com(0x81);
delay(10);
write_date('e');
delay(10);
write_com(0x82);
delay(10);
write_date('m');
delay(10);
write_com(0x83);
delay(10);
write_date('p');
delay(10);
write_com(0x84);
delay(10);
write_date('r');
delay(10);
write_com(0x85);
delay(10);
write_date('a');
delay(10);
write_com(0x86);
delay(10);
write_date(':');
delay(10);
write_com(0x80+14);
delay(10);
write_date(0xDF);
delay(10);
write_com(0x80+15);
delay(10);
write_date('C');
}
//温度处理
void wenduchuli()
{
uint wd;
bai=c/100;//取百位数
shi=c%100/10;//取十位数
ge=c%100%10;//取个位数
wd=0;
if (a & 0x08) wd=wd+5000;
if (a & 0x04) wd=wd+2500;
if (a & 0x02) wd=wd+1250;
if (a & 0x01) wd=wd+625; //以上4条指令把小数部分转换为BCD码形式
shifen=wd/1000; //十分位
baifen=(wd%1000)/100; //百分位
qianfen=(wd%100)/10; //千分位
wanfen=wd%10; //万分位
if(q==0)//正负温度判断
{sign=' ';}
else
{sign='-';}
}
//lcd数据显示
lcd()
{
write_com(0x87);
delay(10);
write_date(sign);
write_com(0x88);
delay(10);
write_date(table[bai]);
write_com(0x89);
delay(10);
write_date(table[shi]);
write_com(0x8a);
delay(10);
write_date(table[ge]);
write_com(0x8b);
delay(10);
write_date('.');
write_com(0x8c);
delay(10);
write_date(table[shifen]);
write_com(0x8d);
delay(10);
write_date(table[baifen]);
}
//产生复位脉冲初始化DS18B20
/**********************************18b20采集程序***********************************/
void Treset(void)
{ uint i;
DQ=0;
//拉低562us
for(i=70;i>0;i--);
//产生上升沿
DQ=1;
//拉高15--60us
for(i=4;i>0;i--);//是34us
}
//等待应答脉冲
void Twait(void)
{
// uint i;
while(DQ);
while(~DQ);//检测是否有单器件在线
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//等待20us是26us
}
//读取数据的一位,满足时间隙要求
bit Rdbit(void)
{
uint i;
bit b;
DQ=0;
_nop_();_nop_();//保持至少1us是2us
DQ=1;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//延时15us以上是20us
b=DQ;
for(i=9;i>0;i--);//读时间隙不低于60us是74us
return(b);
}
//读取数据的一个字节
uchar Rdbyte(void)
{
uchar i,j,b;
b=0;
for(i=1;i<=8;i++)
{
j=Rdbit();
b=(j<<7)|(b>>1);
}
return(b);
}
//写数据的一个字节,满足写1和写0的要求
void Wrbyte(uchar b)
{
uint i;
uchar j;
bit btmp;
for(j=1;j<=8;j++)
{
btmp=b&0x01;
b=b>>1;
if(btmp)
{
//写1
DQ=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//延时,使得15US以内拉高 是10us 改过 for(i=2;i>0;i--)
DQ=1;
for(i=9;i>0;i--);//写时间隙不低于60us 是74us
}
else
{
//写0
DQ=0;
//i=8;
for(i=9;i>0;i--);//保持低电平60us到120us之间 是74us
DQ=1;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
}
//启动温度转换
void convert(void)
{
Treset();//产生复位脉冲初始化DS18B20
Twait(); //等待应答脉冲
delay(5);//延时t毫秒5ms
Wrbyte(0xcc);//skip from命令
Wrbyte(0x44);//convert T命令
}
//读取温度值
void Rdtemp(void)
{
Treset();//产生复位脉冲初始化DS18B20
Twait(); //等待应答脉冲
delay(5);//延时t毫秒5ms
Wrbyte(0xcc);//skip from命令
Wrbyte(0xbe);// read scratchpad 命令
Rl=Rdbyte();//温度值的低位温度
Rh=Rdbyte(); //温度值的高位温度
}
//温度转换
void work_temp()
{
uchar x,y;
a=Rl&0x0f;//低位字节的小数部分
y=((Rl&0xf0)>>4|(Rh&0x0f)<<4);
x=y&0x80;//取符号位
q=x;
if(x)//温度正负判断
{
if(a==0)
c=~y+1;
else
c=~y; //取补码
a=~a+1;
}
else
{c=y;}
}
//温度总处理
void temper()
{
convert();//启动温度转换
Rdtemp(); //读取温度值
work_temp(); //温度转换
wenduchuli(); //温度处理
}
main()
{
lcdinit();//初始化1602
while(1)
{
temper();//温度总处理
lcd();//1602显示
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -