分享

PIC16F877A DS18B20数字温度计实验

 共同成长888 2020-06-25

main.c

#include

#include

#include "def.h"

#include "ds18b20.h"

 

__CONFIG(0xFF32);

 

void Delay_ms(u16 xms)

{

  int i,j;

  for(i=0;i<>< p=""><>

  { for(j=0;j<71;j++) ; }

}

 

void uart_init(void)

{

    TXSTA=0x24; //开启发射使能位、高波特率,TRMT初始值可0可1

    RCSTA=0x80;

    SPBRG=0x19; //4M晶振,波特率9600,则SPBRG初值为25

}

 

//printf函数重定向

void putch(u8 c)

{

    TXREG = c;

    while(TRMT==0);

}

 

short temperature;

 

void main()

{

uart_init();

Delay_ms(5);

printf("ds18b20 demo\n");

while(1)

{

if(Init_18B20()==0)

{

printf("init ok1!\n");

Skip();

Convert();

Delay_ms(750);

if(Init_18B20()==0)

{

printf("init ok2!\n");

Skip();

Read_SP();

RomCode[0]=Read_18B20();

RomCode[1]=Read_18B20(); 

temperature=ReadTemp(RomCode);

temperature=CalcTemp(temperature);

printf("code=%02x%02x\t->\t%d.%d℃\n",RomCode[0],RomCode[1],temperature/10,temperature%10);

}

}

Delay_ms(3000);

}

}

ds18b20.h

#include

#include "def.h"

 

#ifndef __ds1820_h

#define __ds1820_h

 

extern u8 RomCode[2];

 

#define DQ1     RC1=1

#define DQ0     RC1=0

#define DQ_in   TRISC1=1

#define DQ_out  TRISC1=0

#define DQ_val  RC1

 

#define _DINT() di()

#define _EINT() ei()

#define _NOP() asm("nop")

 

 

u8 Init_18B20(void);

short CalcTemp(short a);

void Skip(void);

void Convert(void);

void Read_SP(void);

u8 Read_18B20(void);

short ReadTemp(u8 *r);

 

#endif

ds18b20.c

/*********************************

PIC16F877A@4MHz

*********************************/

#include "ds18b20.h"

#include "def.h"

 

u8 RomCode[2];

 

#define DelayNus _delay

 

u8 Init_18B20(void)

{

  u8 Error;

  

  DQ_out;

  _DINT();

  DQ0;

  DelayNus(500); //延迟至少480us

  DQ1;

  DelayNus(55);  //释放DQ后延时120us(60~240)后再读数

  DQ_in;

  _NOP();

  if(DQ_val)      

    Error = 1;   //初始化失败

  else

    Error = 0;   //初始化成功

  DQ_out;

  DQ1;

  _EINT();

  

  DelayNus(400);

  

  return Error;

}

 

void Write_18B20(u8 wdata)

{

  u8 i;

  

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

  {

    _DINT();

    DQ0;

    //DelayNus(6);     //延时2us

    _NOP();

    _NOP();

    _NOP();

    _NOP();

    _NOP();

    _NOP();

    _NOP();

    _NOP();

    if(wdata & 0X01)    

    DQ1;

    else                

    DQ0;

    wdata >>= 1;

    

    DelayNus(70);     //延时91us 

    DQ1;

    _EINT();

    _NOP();

  } 

}

 

 

u8 Read_18B20(void)

{

  u8 i;

  u8 temp = 0;   

  

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

  {

    temp >>= 1;

    _DINT();   

    DQ0;

    _NOP();

    _NOP();

    _NOP();

    _NOP();

 

    DQ1;

    //DelayNus(8);            //延时9us

    DQ_in;

    //DelayNus(25);           //延时45us

    if(DQ_val)   

      temp |= 0x80;    

    DQ_out;

    DQ1;

    DelayNus(70);           //延时10us

    _EINT();

    _NOP();

  }      

  return  temp;

}

 

void Skip(void)

{

    Write_18B20(0xcc);

}

 

void Convert(void)

{

    Write_18B20(0x44);

}

 

void Read_SP(void)

{

    Write_18B20(0xbe);

}

 

short ReadTemp(u8 *r)

{

    u8 temp_low;

    short temp;

    

    temp_low = r[0];      //读低位

    temp = r[1];          //读高位

    temp = (temp<<8) | temp_low;

    return  temp;

}

 

const u8 dottab[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};

//优化读数算法

short CalcTemp(short a)

{

  u8 b;

  

  if(a<0)

  {

    a=~a;

    a++; 

    b=a;

    a>>=4;

    a*=-10;

    a-=dottab[b&0x0f];    

  }

  else

  {

    b=a;

    a>>=4;

    a*=10;

    a+=dottab[b&0x0f];       

  }

 

  return a;

}

 

 

def.h

#ifndef __DEF__H_

#define __DEF__H_

 

#define u8 unsigned char

#define u16 unsigned int

 

#endif

 

关键字:PIC16F877A  DS18B20  数字温度计 编辑:什么鱼 引用地址:http://news.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多