/***********************************************************************
* 采用四位共阴极数码管琒R42056K,P1口接数码管段码。P0.0接第一位
* P0.1接第二位,p0.2接第三位,p0.3接第四位。
* 单片机AR89S52,晶振7.3728M
* DS18B20接P2.0。
*
***********************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
/***********************************************************************
* DS18B20 数据口 DQ
* 共阴极数码管
*共阴极数码管带小数点
***********************************************************************/
//#define DQ RC1
//#define DQ_HIGH() TRISC1=1
//#define DQ_LOW() TRISC1=0;DQ=0
//__CONFIG(0x3B31);
sbit DQ=P2^0;
//const uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
// 0x07,0x7f,0x6f};
unsigned char code table[]={//共阴极0~f数码管编码
0x3f,0x06,0x5b,0x4f, //0~3
0x66,0x6d,0x7d,0x07, //4~7
0x7f,0x6f,0x77,0x7c, //8~b
0x39,0x5e,0x79,0x71 //c~f
};
//const uchar table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
// 0x87,0xff,0xef};
const uchar table1[]={
0xbf,0x86,0xdb,0xcf,//0-3
0xe6,0xed,0xfd,0x87,//4-7
0xff,0xef//8-9
};
uint temper;//温度值缓存
uchar a1,a2,a3,a4;//数码管每个位上显示的数字
uchar time=0;//延时缓存
uchar TH; //判断负值
void delay(uint x);
void delayus(uint,uchar);
void init();//初始化
void disp(uchar num1,uchar num2,uchar num3,uchar num4);//正值显示
void disp1(uchar num1,uchar num2,uchar num3);//负值显示
void write_byte(uchar date);
void delayms(uchar i); //误差 -0.651041666667us
uchar read_byte();
void get_tem();//获取温度
void delay20us();
void delay30us();
void delay45us();
void delay70us();
void delay750us();
void delay500us();
void InitTimer0(void);
void delay20us(void) //误差 -0.46875us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=3;a>0;a--);
}
void delay30us(void) //误差 -0.703125us
{
unsigned char a,b;
for(b=3;b>0;b--)
for(a=1;a>0;a--);
}
void delay45us(void) //误差 -1.0546875us
{
unsigned char a;
for(a=12;a>0;a--);
}
void delay70us(void) //误差 -0.013020833333us
{
unsigned char a;
for(a=20;a>0;a--);
}
void delay750us(void) //误差 -1.302083333333us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=227;a>0;a--);
}
void delay500us(void) //误差 -0.325520833333us
{
unsigned char a;
for(a=152;a>0;a--);
}
void InitTimer0()
{
TMOD = 0x01;
TH0 = 0x88;
TL0 = 0x00;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void main()
{
init();
InitTimer0();
while(1)
{
uchar num;
for(num=100;num>0;num--)
{
if(TH<0X7F)
disp(a1,a2,a3,a4);
else
disp1(a1,a2,a3);
}
}
}
/***********************************************************************
* 复位18B20
***********************************************************************/
void reset()
{
uchar st=1;
// DQ_HIGH();
DQ=1;
// NOP();NOP();
_nop_();
while(st)
{
// DQ_LOW();
DQ=0;
// delayus(70,30);
delay750us();
// DQ_HIGH();
DQ=1;
// delayus(4,4);
delay70us();
if(DQ==1)
st=1;
else
st=0;
//delayus(50,10);
delay500us();
}
}
/***********************************************************************
* 写字节
***********************************************************************/
void write_byte(uchar date)
{
uchar i,temp;
// DQ_HIGH();
DQ=1;
// NOP();NOP();
_nop_();
for(i=8;i>0;i--)
{
temp=date&0x01;//01010101
// DQ_LOW();
DQ=0;
// delayus(0,0);
delay20us();
if(temp==1)
// DQ_HIGH();
DQ=1;
// delayus(2,2);
delay45us();
// DQ_HIGH();
DQ=1;
date=date>>1;//00101010
}
}
/***********************************************************************
* 读字节
***********************************************************************/
uchar read_byte()
{
uchar i,date;
static bit j;
for(i=8;i>0;i--)
{
date=date>>1;
// DQ_HIGH();
DQ=1;
// NOP();NOP();
_nop_();
// DQ_LOW();
DQ=0;
// NOP();NOP();NOP();NOP();NOP();NOP();
_nop_();_nop_();
// DQ_HIGH();
DQ=1;
// NOP();NOP();NOP();NOP();
_nop_();
j=DQ;
if(j==1)
date=date|0x80;//1000 0000
// delayus(1,1);
delay30us();
}
return (date);
}
/***********************************************************************
* 温度获取
***********************************************************************/
void get_tem()
{
uchar tem1,tem2;
float aaa;
reset(); //复位
write_byte(0xCC);//跳过ROM
write_byte(0x44);//温度转换
reset();
write_byte(0xCC);
write_byte(0xBE);
tem1=read_byte();
tem2=read_byte();
TH=tem2;
if(tem2>0x7f)
tem2=~tem2;
aaa=(tem2*256+tem1)*6.25;
temper=(int)aaa;
a1=temper/1000;
a2=temper%1000/100;
a3=temper%100/10;
a4=temper%10;
}
/***********************************************************************
* 清屏
***********************************************************************/
void init()
{
P1=0x00;
P0=0xff;
}
/***********************************************************************
* 正温度时,显示
*
***********************************************************************/
void disp(uchar num1,uchar num2,uchar num3,uchar num4)
{
P1=table[num1];
P0=0xfe;
delayms(2);
P1=table1[num2];
P0=0xfd;
delayms(2);
P1=table[num3];
P0=0xfb;
delayms(2);
P1=table[num4];
P0=0xf7;
delayms(2);
}
/***********************************************************************
* 负温度时,显示
*
***********************************************************************/
void disp1(uchar num1,uchar num2,uchar num3)
{
P1=0x40;//显示负号
P0=0xfe;
delayms(2);
P1=table[num1];
P0=0xfd;
delayms(2);
P1=table1[num2];
P0=0xfb;
delayms(2);
P1=table[num3];
P0=0xf7;
delayms(2);
}
/***********************************************************************
* 毫秒级的延时
* 晶振7.3728M
***********************************************************************/
void delayms(uchar i) //误差 -0.651041666667us
{
uchar a,b;
for(;i>0;i--)
for(b=47;b>0;b--)
for(a=5;a>0;a--);
}
/***********************************************************************
* 定时器0中断服务程序, 设置20毫秒计时器。每1秒钟采集一次温度值
*
***********************************************************************/
void Timer0Interrupt(void) interrupt 1
{
TH0 = 0x88;
TL0 = 0x00;
//add your code here!
time++;
if(time==20)
{
time=0;
get_tem();
}
}