PIC16F877A DS18B20数字温度计实验

main.c

#include <htc.h>
#include <stdio.h>
#include "def.h"
#include "ds18b20.h"

__CONFIG(0xFF32);
 
void Delay_ms(u16 xms)
{
 	int i,j;
 	for(i=0;i<xms;i++)
 		{ 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 <htc.h>
#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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值