📄 ds18b20.c
字号:
/*********************************************************************************************/
//单总线数字温度传感器DS18B20驱动程序
//---------------------------------------------------------------------
//连接方式:
// DQ:IOB15
//---------------------------------------------------------------------
//日期: 2008.08.30
//作者: LiPeng
/*********************************************************************************************/
#include "SPCE061A.H"
#include "ds18b20.h"
/*外部函数声明*/
extern void Set_System_Clock();
extern void Renew_System_Clock();
extern void F_18B20_Delaynus(unsigned int n);
extern void Disp_Strs(int line,int row,char *strings);
/*********************************************************************/
//功能: IO口初始化
//参数: 无
//返回值: 无
/*********************************************************************/
void F_18B20_IOInitial()
{
*P_IOB_Dir&=(0xffff-0x8000);//定义IOB15为悬浮式输入端口,以后如若
*P_IOB_Attrib|=0x8000; //写数据,只需将*P_IOB_Dir数据更改即可
*P_IOB_Data|=0x8000;
}
/*********************************************************************/
//功能: 将IOB15更改为输出口
//参数: 输入输出标志,'1'代表输出,反之为输入
//返回值: 无
/*********************************************************************/
void F_18B20_ChgIODir(unsigned int DirFlag)
{
if(DirFlag)//'1',更改为输出
*P_IOB_Dir|=0x8000;
else
*P_IOB_Dir&=(0xffff-0x8000);//否则,更改为输入
}
/*********************************************************************/
//功能: 写时序-写1
//参数: 无
//返回值: 无
/*********************************************************************/
void F_18B20_Write1()
{
F_18B20_ChgIODir(1);//将IOB15更改为输出
DQ_L;
F_18B20_Delaynus(5);//主机拉低单总线15us内释放总线,则向单总线器件写1
F_18B20_ChgIODir(0);//恢复IOB15为悬浮式输入
F_18B20_Delaynus(50);//读写时序至少60us,实现延时控制读写时间
}
/*********************************************************************/
//功能: 写时序-写0
//参数: 无
//返回值: 无
/*********************************************************************/
void F_18B20_Write0()
{
F_18B20_ChgIODir(1); //将IOB15更改为输出
DQ_L;
F_18B20_Delaynus(70);//主机拉低单总线至少保持60us低电平,则向单总线器件写0
F_18B20_ChgIODir(0); //恢复IOB15为悬浮式输入
}
/*********************************************************************/
//功能: 读时序-读一位数据
//参数: 无
//返回值: 读出的一位数据值
/*********************************************************************/
unsigned int F_18B20_ReadDQ()
{
unsigned int ReadTemp=0;
F_18B20_ChgIODir(1); //将IOB15更改为输出
DQ_L;
F_18B20_Delaynus(2); //注意此处时序,更改有可能造成读取错误
F_18B20_ChgIODir(0); //恢复IOB15为悬浮式输入
F_18B20_Delaynus(2);
ReadTemp=*P_IOB_Data;//读入DQ线值
F_18B20_Delaynus(40);
ReadTemp&=0x8000;
ReadTemp>>=8;
return ReadTemp;
}
/*********************************************************************/
//功能: 向单总线器件写1字节
//参数: 要写入的字节数据
//返回值: 无
/*********************************************************************/
void F_18B20_WriteByte(unsigned int Data)
{
unsigned int ByteCnt;
for(ByteCnt=0;ByteCnt<8;ByteCnt++)
{
CL_Wdog;
if(Data&0x01)
F_18B20_Write1();
else
F_18B20_Write0();
Data>>=1;//低位开始写起,依次右移8次
}
}
/*********************************************************************/
//功能: 从单总线器件读1字节
//参数: 无
//返回值: 读出的字节数据
/*********************************************************************/
unsigned int F_18B20_ReadByte()
{
unsigned int ByteCnt,ReadData=0x00;
for(ByteCnt=0;ByteCnt<8;ByteCnt++)
{
CL_Wdog;
ReadData>>=1;
ReadData|=F_18B20_ReadDQ();//低位在前,每次右移一位
}
return ReadData;
}
/*********************************************************************/
//功能: 复位
//参数: 无
//返回值: 0表示复位失败,反之成功
/*********************************************************************/
unsigned int F_18B20_Reset()
{
unsigned int InputTemp,OverTimeFlag;
F_18B20_ChgIODir(1); //将IOB15更改为输出
DQ_L;
F_18B20_Delaynus(600);//主机拉低总线至少480us产生复位脉冲
F_18B20_ChgIODir(0); //恢复IOB15为悬浮式输入,释放总线
F_18B20_Delaynus(60); //注意该处延时,单总线器件等待时间,修改可能导致复位错误
for(OverTimeFlag=5;OverTimeFlag>0;OverTimeFlag--)//单总线器件拉低总线60-240us作为应答脉冲
{
CL_Wdog;
InputTemp=*P_IOB_Data;
InputTemp&=0x8000;
if(InputTemp)
return 0;
}
return 1;
}
/*********************************************************************/
//功能: 初始化18B20
//参数: 无
//返回值: 0表示初始化失败,反之成功
/*********************************************************************/
unsigned int F_18B20_Initial()
{
Set_System_Clock();//设置系统时钟
F_18B20_IOInitial();
if(F_18B20_Reset())
{
Renew_System_Clock();//恢复系统时钟
return 1;
}
else
{
Disp_Strs(1,1,"Init Failed...");
Renew_System_Clock();//恢复系统时钟
return 0;
}
}
/*********************************************************************/
//功能: 启动18B20测温
//参数: 无
//返回值: float型温度值
/*********************************************************************/
float F_18B20_Start()
{
int uintTemp=0;
float fTemp=0.0;
unsigned int Data[9];
Set_System_Clock();
if(F_18B20_Reset())
{
F_18B20_WriteByte(0xcc); //Skip ROM,单点总线系统,不需读取分辨
F_18B20_WriteByte(0x44); //Start one convert
while(F_18B20_ReadDQ()==0) //启动后发送读操作,若器件忙于温度转化则输出0,转化完毕输出1
{
CL_Wdog;
}
F_18B20_Reset(); //一次完整操作包括初始化,ROM操作,存储器和控制操作,处理数据四步,每次都要遵循该流程
F_18B20_WriteByte(0xcc); //Skip ROM
F_18B20_WriteByte(0xbe); //Read Scratchpad,读缓冲寄存器
for(uintTemp=0;uintTemp<9;uintTemp++)
{
CL_Wdog;
Data[uintTemp]=F_18B20_ReadByte();
}
uintTemp=(Data[1]<<8)|Data[0]; //缓冲存储器中的Byte0、1数据为测得的温度信息,以16位补码形式存放
if(uintTemp&0x8000)
uintTemp=(~uintTemp)+1;
fTemp=(float)uintTemp;
fTemp=fTemp*0.0625; //获得最终温度输出
}
Renew_System_Clock();
return fTemp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -