📄 temp2.c
字号:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar c[4]={0x08,0x04,0X02,0x01};
uchar seg7[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
uchar dot_seg[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
uchar dis[5]={0x10,0x10,0x10,0x10, 0x00};
uchar tplsb,tpmsb;
uchar tick0=30;
uchar flaga;
sbit DQ=P3^7;
/* ********************延时t毫秒 ***************************/
void delay(uint t)
{
uchar m;
while(t--)
{
for (m=0;m<125;m++)
;
}
}
/********************* 产生复位脉冲初始化DS18B20 **************************/
void TxReset(void)
{
uint i;
DQ = 0;/* 拉低约900us */
for(i = 100; i > 0; i--)
;
DQ = 1; // 产生上升沿
for(i = 4; i > 0; i--)
;
}
/* ***********************等待应答脉冲 *********************/
void RxWait(void)
{
uint i;
while(DQ)
;
while(~DQ)
; // 检测到应答脉冲
for(i = 4; i > 0; i--)
;
}
/***************** 读取数据的一位,满足读时隙要求 *************************/
bit RdBit(void)
{
uint i;
bit b;
DQ = 0;
i++;
DQ=1;
i++;
i++; // 延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效
b = DQ;
for(i = 8; i > 0; i--)
;
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;
i++;
i++; // 延时,使得15us以内拉高
DQ=1;
for(i = 8; i > 0; i--)// 整个写1时隙不低于60us
;
}
else
{
/* 写0 */
DQ = 0;
for(i = 8; i > 0; i--)// 保持低在60us到120us之间
;
DQ = 1;
i++;
i++;
}
}
}
/* **************启动温度转换 *******************/
void convert(void)
{
TxReset(); // 产生复位脉冲,初始化DS18B20
RxWait(); // 等待DS18B20给出应答脉冲
delay(1); // 延时
WrByte(0xcc); // skip rom 命令
WrByte(0x44); // convert T 命令
}
/**************** 读取温度值 *********************/
void RdTemp(void)
{
TxReset(); // 产生复位脉冲,初始化DS18B20
RxWait(); // 等待DS18B20给出应答脉冲
delay(1); // 延时
WrByte(0xcc); // skip rom 命令
WrByte(0xbe); // read scratchpad 命令
tplsb = RdByte(); // 温度值低位字节(其中低4位为二进制的“小数”部分)
tpmsb = RdByte(); // 高位值高位字节(其中高5位为符号位)
}
//*************************8数据处理程序************************//
void datadeal(void)
{
uchar temp1,temp2;
int tt;
int tm;
tm = tpmsb << 8;
tm = tm | tplsb;
if(tm < 0)
tm = 0 - tm;
temp2 = tm & 0x0f;
temp1 = (tm >> 4) & 0xff;
if(dis[0] == 0)
dis[0] = 16;
dis[1] = temp1 / 10 % 10;
dis[2] = temp1 % 10;
flaga = tpmsb >> 3;
flaga = flaga & 0x01;
tt = tplsb & 0x0f;
if(flaga == 0)
tt = 625*tt;
else
{
tt = 0 - tt;
tt = tt & 0x0f;
tt = tt * 625;
}
dis[3] = tt / 1000;
dis[4] = tt / 100 % 10;
dis[5] = tt / 10 % 10;
if(dis[1] >= 5)
P1 = 0x08;
else
P1 = 0x20;
if(dis[1] == 0)
dis[1] = 16;
if(dis[4] > 4)
dis[4] = dis[4]+1;
if(dis[4] > 9)
dis[2] += 1;
if(dis[2] > 9)
dis[1] += 1;
}
//**************显示程序****************//
void display(void) interrupt 1
{
static uchar i;
TH0 = 0xD8;
TL0 = 0xF0;
P2 = c[i];
if(i == 0)
{
if(flaga)
P0 = 0xbf;
else
P0 = seg7[dis[1]];
}
else if(i == 1)
P0 = dot_seg[dis[i+1]];
else
P0 = seg7[dis[i+1]];
i = (i + 1) % 4;
}
void initINT(void)
{
TMOD = 0x01;
TH0 = 0xD8;
TL0 = 0xF09;
ET0 = 1;
EX0 = 1;
TR0=1;
EA = 1;
}
/* 主程序,读取的温度值最终存放在tplsb和tpmsb变量中。
tplsb其中低4位为二进制的“小数”部分;tpmsb其中高
5位为符号位。真正通过数码管输出时,需要进行到十进
制有符号实数(包括小数部分)的转换。*/
void main(void)
{
initINT();
P0=0xff;
P1 = 0;
while(1)
{
convert(); // 启动温度转换,需要750ms
RdTemp(); // 读取温度
datadeal();
delay(200);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -