📄 ds18b20.h
字号:
/********************************************************************
//AVR系统的处理器为: ATmega32
//AVR系统的晶振频率: 8.0000 Mhz
********************************************************************/
#ifndef _DS18B20_H
#define _DS18B20_H
#include <iom32v.h>
#include <macros.h>
#include "delay.h"
//ds18b20相关引脚对应端口定义
#define DS18B20_PORT PORTD
#define DS18B20_PIN PIND
#define DS18B20_DDR DDRD
#define DS18B20_IO PD4
//ds18b20相关引脚操作定义
#define CLR_DS18B20 DS18B20_PORT &=~ BIT(DS18B20_IO) //数据线强制拉低
#define SET_DS18B20 DS18B20_PORT |= BIT(DS18B20_IO) //数据线强制拉高
#define HLD_DS18B20 DS18B20_DDR |= BIT(DS18B20_IO) //控制总线设为输出
#define RLS_DS18B20 DS18B20_DDR &=~ BIT(DS18B20_IO) //释放总线设为输入
#define STU_DS18B20 DS18B20_PIN & BIT(DS18B20_IO) //数据线的状态
/**********************************************************************
//DS18B20初始化
**********************************************************************/
unsigned char resetDS18B20(void)
{
unsigned char errTime=0;
RLS_DS18B20; //释放总线
_NOP();
HLD_DS18B20; //Maga16控制总线
CLR_DS18B20; //强制拉低
Delay_Us(480); //209.42us
//以上延时大于480us
RLS_DS18B20; //释放总线,总线自动上拉
_NOP();
while(STU_DS18B20)
{
Delay_Us(6); //5.15us
errTime++;
if(errTime>20)
return(0x00); //如果等带大于约 5.15us*20就返回0x00,报告复位失败(实际上只要等待15-60us)
}
errTime=0;
while(!(STU_DS18B20))
{
Delay_Us(6); //5.15us
errTime++;
if(errTime>50)
return(0x00); //如果等带大于约 5.15us*50就返回0x00,报告复位失败(实际上只要等待60-240us)
}
return(0xff);
}
/**********************************************************************
//读DS18B20一个字节
**********************************************************************/
unsigned char readByteDS18B20(void)
{
unsigned char i;
unsigned char retVal=0;
RLS_DS18B20; //释放总线
for(i=8;i>0;i--)
{
retVal>>=1;
HLD_DS18B20; //Maga16控制总线
CLR_DS18B20; //强制拉低
Delay_Us(8); //延时大于1us
SET_DS18B20; //释放总线,DS18B20会将总线强制拉低
//delay_nus(8);
RLS_DS18B20; //释放总线
if(STU_DS18B20)
retVal|=0x80;
Delay_Us(32); //31us
HLD_DS18B20; //释放总线
SET_DS18B20; //释放总线,DS18B20会将总线强制拉低
//delay_nus(30); //30.38us
}
Delay_Us(5); //2.71us(大于1us就行了)
return(retVal);
}
/**********************************************************************
//写DS18B20一个字节
**********************************************************************/
void writeByteDS18B20(unsigned char wb)
{
unsigned char i;
unsigned char temp;
RLS_DS18B20; //释放总线
for(i=0;i<8;i++)
{
HLD_DS18B20; //Maga16控制总线
CLR_DS18B20; //强制拉低
Delay_Us(4); //14.92us
//SET_DS18B20; //释放总线
//delay_nus(16); //14.92us
temp=wb>>i;
temp&=0x01;
if(temp)
SET_DS18B20; //释放总线
else
CLR_DS18B20; //强制拉低
Delay_Us(50); //30.38us
//RLS_DS18B20; //释放总线
SET_DS18B20; //释放总线
Delay_Us(4); //2.71us(大于1us就行了)
}
}
/**********************************************************************
//读DS18B20温度
**********************************************************************/
unsigned int readTempDS18B20(void)
{
unsigned char tempL,tempH;
unsigned int x;
//resetDS18B20();
//writeByteDS18B20(0xcc); //跳过ROM
//writeByteDS18B20(0x44); //启动温度转换
Delay_Ms(1); //等待1ms
resetDS18B20();
writeByteDS18B20(0xcc); //跳过ROM
writeByteDS18B20(0xbe); //读数据
tempL=readByteDS18B20();
tempH=readByteDS18B20();
x=(tempH<<8)|tempL;
resetDS18B20();
writeByteDS18B20(0xcc); //跳过ROM
writeByteDS18B20(0x44); //启动温度转换
return(x);
}
float DS18B20_FLOAT_Temp(void)
{
unsigned int temp=0;
unsigned char is_negative=0; //默认为不是负温度
float temperature=0;
temp=readTempDS18B20(); //读出16位数据
if(temp==0xf800) //即是-128°C,不能处理 下面的temp&=0x07ff;、temp=2048-temp;会出错
{
temp=0xf801; //变成 -127.9375°C
}
//判断正负,并进行求原码的操作
if(temp>=256*8) //高5位都为1,则为负温度
{
is_negative=1; //判断为负温度
temp&=0x07ff; //把高5位复位为零
temp=2048-temp; //补码转换成原码(模减去当前值),符号变正,待会求绝对值
}
else
is_negative=0; //正数的原码是它本身
temperature = temp;
temperature = temperature * 0.0625;
if(is_negative) //如果之前判断为负值,现在要把其变为负值
temperature=-temperature;
return(temperature);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -