📄 hk.c
字号:
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar Rl,Rh;//温度低位,温度高位
uchar a,c;//中间变量
sbit DQ=P3^7;//数据通信线
uchar ge, shi, bai, shifen,baifen,qianfen,wanfen;//数组表示温度的每位 个 十 百 小数位
code unsigned char table[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x19};
//0 1 2 3 4 5 6 7 8 9 共阳编码
uchar flag;
//延时t毫秒
void delay(uint t)
{ uint i,j;
for(i=t;i>0;i--)
for(j=130;j>0;j--);
}
//产生复位脉冲初始化DS18B20
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()
{ uint wd;
a=Rl&0x0f;//低位字节的小数部分
c=((Rl&0xf0)>>4|(Rh&0x0f)<<4);
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; //万分位
}
void scanf()
{
P0=table[bai];//送段码
P2=0x10; //送位码
delay(4);
P0=table[shi];
P2=0x20;
delay(6);
P0=table[ge]&0xfe;//一起显示小数位
P2=0x40;
delay(5);
P0=table[shifen];
P2=0x80;
delay(1);
/*P0=table[xiaoshu2];
P2=0x10; */
//delay(5);
}
void tongxin()
{
TMOD=0x20;
TH1=0xFd;
TL1=0xFd;//设置9600的波特率,定时计数器1的工作方式2? TR1=1;
SM0=0;
SM1=1;//串口为工作方式1。
REN=1;//允许接收
EA=1;
ES=1;//开中断? //PCON=0x80;
}
void fuwu() interrupt 4
{
flag=1;//置标志位? RI=0;
TI=0;
}
main()
{
tongxin();
convert(); //开始转换数据
Rdtemp(); //读取数据
work_temp();//温度处理
scanf();
if(flag==1)
{
flag=0;//标志位置零,准备下次用。
ES=0;//关中断防止多次发送。
SBUF=a;//发送小数部分
delay(1);
SBUF=c;//发送整数部分
ES=1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -