专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

AT89S52与DS18B20数字温度传感器测试结束

作者:佚名   来源:本站原创   点击数:  更新时间:2012年10月11日   【字体:

/*********************************************************************** 
* 采用四位共阴极数码管琒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();
 }
}
关闭窗口

相关文章