单片机使用DS18B20测量温度的程序

//main.c

#include <iom16v.h>   

#include <macros.h>

#include 18B20.h

#includedisp.h

#define  uint  unsigned int

#define  uchar unsigned char

const uchar shu[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,

                    0x82,0xF8,0x80,0x90};

const uchar bshu[3]={0xff,0xf9,0xbf};

    

//延时函数在4M时延时1ms

void s_1ms(unsigned int ms)

{

    unsigned int aa;

 for(;ms>=1;ms--)

 {

 for(aa=0;aa<=800;aa++)

 {;}

 }

}

void main()

{

uint wendu,xiao,ge,shi,bai;

uchar  fh;

DDRA = 0xff;    

PORTA = 0xff;    

s_1ms(200); //延时200ms

ds1820_reset();   //DS18B20复位 

while (1)

  {

  ds1820_start();  

 

  wendu = ds1820_read_temp();   //读取温度数值

 

  fh=ds1820_fh();

 

  if(fh)

  {

  wendu=~(wendu)+1;

   wendu = (wendu * 10)/ 16;        //数值处理

 

      wendu = wendu % 1000; 

 

  shi= wendu / 100;  //显示第2位

  wendu = wendu % 100;

  ge= wendu / 10;   //显示ge位

  xiao=wendu % 10;    // 显示小数位

 

 

   display(0,shu[xiao]);  //小数位

   display(1,shu[ge]&0x7f);  //个位

   display(2,shu[shi]);    //shi

   display(3,bshu[2]);   //bai位,0不显示

   }

 

   else

   {

   wendu = (wendu * 10) / 16;        //数值处理

 

  bai = wendu / 1000;    //bai位

  wendu = wendu % 1000; 

 

  shi= wendu / 100;  //显示第2位

  wendu = wendu % 100;

  ge= wendu / 10;   //显示ge位

  xiao=wendu % 10;    // 显示小数位

 

 

   display(0,shu[xiao]);  //小数位

   display(1,shu[ge]&0x7f);  //个位

   display(2,shu[shi]);    //shi

   display(3,bshu[bai]);   //bai位,0不显示

   }

  }

}

 

//18B20.h

 #define uchar unsigned char

#define uint  unsigned int

//设置成输入

#define DQ_INPUT   DDRC &= ~BIT(7)

//设置成输出

#define DQ_OUT     DDRC |= BIT(7)

//设置成低电平

#define DQ_LO      PORTC &= ~BIT(7)

//设置成高电平

#define DQ_HI      PORTC |= BIT(7) 

//读出

#define DQ_R       PINC & BIT(7)    

//中断标志

uchar init_f;   

//延时函数

void delay_us(uint ms)

{

    uchar  tm;

 while(ms--)

 {

  for(tm=0;tm<2;tm++);

  }

}

//DS18B20复位

void ds1820_reset(void)

{

 uchar i;

 //中断保护

 init_f = SREG;  

 //关中断

 CLI();    

 DQ_OUT;

 DQ_LO;

 delay_us(80);    //延时500us

 DQ_HI;

 DQ_INPUT;

 delay_us(10);     //延时80us

 i = DQ_R;

 delay_us(80);    //延时500us

 if (init_f & 0x80)  //恢复中断状态

  { 

  SEI();      

  }

}

//DS18B20字节读取

uchar ds1820_read_byte(void)

{

 uchar i;

 uchar value = 0;

 //中断保护

 init_f = SREG;

 //关中断  

 CLI();    

 for (i = 8; i != 0; i--) {

  value >>= 1;

  DQ_OUT;

  DQ_LO;

  delay_us(2);

  DQ_HI;

  DQ_INPUT;

  if (DQ_R)

   {

      value|=0x80;

   }

  delay_us(10);   //延时60us

  }

 if (init_f&&0x80) //恢复中断状态

 { 

  SEI();

  }

 return(value);

}

//DS18B20字节写入

void ds1820_write_byte(unsigned char value)

{

 uchar i;

 init_f = SREG; 

 CLI();    

 for (i = 8; i > 0; i--)

 {

  DQ_OUT;

  DQ_LO;

  if (value & 0x01)

   {

    DQ_HI;

   }

     delay_us(10);   //延时80us

     DQ_HI;   

     value >>= 1;

  }

    if (init_f & 0x80)//恢复中断状态

     { 

       SEI();

      }

}

//启动ds1820转换

void ds1820_start(void)

{

 ds1820_reset();

 ds1820_write_byte(0xCC); //勿略ROM

 ds1820_write_byte(0x44); //启动转换

}

//读温度

uint ds1820_read_temp(void)

 {

 uint i,wendu;

 uchar buf[2];

 ds1820_reset();

 ds1820_write_byte(0xCC); //勿略ROM

 ds1820_write_byte(0xBE); //读温度

 for (i = 0; i < 2; i++)

  {

  buf[i] = ds1820_read_byte();

  }

   wendu = (buf[1]<<8)|buf[0];

 return wendu;

}

uint ds1820_fh(void)  //读正负温度符号

 {

 uint i,bb;

 uchar buf[2];

 ds1820_reset();

 ds1820_write_byte(0xCC); //勿略ROM

 ds1820_write_byte(0xBE); //读温度

 for (i = 0; i < 2; i++)

  {

  buf[i] = ds1820_read_byte();

  }

  bb=buf[1]&0xf0;

 return bb;

}

 

 //disp.h

#define    uchar unsigned char

#define    uint  unsigned int

#define  SHCP_0   PORTA&=~BIT(1)

#define  SHCP_1   PORTA|=BIT(1)

#define  DS_0     PORTA&=~BIT(3)

#define  DS_1     PORTA|=BIT(3)

#define  STCP_0   PORTA&=~BIT(2)

#define  STCP_1   PORTA|=BIT(2)

  

void  CKin()

{

   SHCP_0;

  NOP();

  SHCP_1;

}

void  Dataout()  //并行输出

{

 STCP_0;

 NOP();

 STCP_1;

}

void Datein( uchar  date )  //数据串行输入

{

 uchar  i,mod;

 DDRA=0xff;

    for(i=0;i<8;i++)

  {

   mod=date&0x80;

    if(mod==0x80)

    {DS_1;}

   else

    {DS_0;}

    CKin();

   date<<=1;          

  }

 Dataout();  //并行输出

}

void  weihao(uchar add)

{

    DDRA=0xff;

 switch(add)

 {

   case 0:PORTA=0x1f;break;

  case 1:PORTA=0x1f|0x80;break;

  case 2:PORTA=0x1f|0x40;break;

  case 3:PORTA=0x1f|0xc0;break;

  case 4:PORTA=0x1f|0x20;break;

  case 5:PORTA=0x1f|0xA0;break;

  case 6:PORTA=0x1f|0x60;break;

  case 7:PORTA=0x1f|0xE0;break;

  default:break;

 }

 

}

void   DELAY(uint  tt)

{

    uint mm;

   while(tt--)

   {

       for(mm=30;mm>0;mm--);

   }

}

void display(uchar wei,uchar data)

{

      weihao(wei);

   Datein(data);

   DELAY(20);

   weihao(wei);

   Datein(0xff);

}