📄 ds18b20.c
字号:
//文件名:DS18B20.C
#include "hardware.h"
asm(".include hardware.inc");
#define DS18B20ANDMASK 0xfffe
#define DS18B20ORMASK 0x0001
#define SIGNALZERO 0x0001
#define TANDMASK DS18B20ANDMASK
#define TORMASK DS18B20ORMASK
#define SEARCHROM 0x00f0
#define READROM 0x0033
#define MATCHROM 0x0055
#define SKIPROM 0x00cc
#define ALARMSEARCH 0x00ec
#define CONVERTT 0x0044
#define WRITESCRATCHPAD 0x004e
#define READSCRATCHPAD 0x00be
#define COPYSCRATCHPAD 0x0048
#define RECALLEE 0x00b8
#define READPOWERSUPPLY 0x00b4
/* This function waits for 1 ms. */
void Wait1ms(void)
{
int cnt = 0;
while (cnt < 392) cnt++;
}
/* This function waits for N ms. */
void WaitNms(int n)
{
int i;
for(i = 1; i <= n; i++) Wait1ms();
}
//初始化DS18B20
void ds18b20_init()
{
unsigned int TempDir,TempAttr,TempData,TempBuf;
//IOB0输出低电平480us
asm("%0=[P_IOB_Attrib]":"=r"(TempAttr));
asm("%0=[P_IOB_Dir]":"=r"(TempDir));
asm("%0=[P_IOB_Data]":"=r"(TempData));
TempDir|=TORMASK;
TempAttr&=TANDMASK;
TempData|=TORMASK;
SP_Init_IOB(TempDir,TempAttr,TempData);
HDM_DELAY_480us();
//输出15us的高电平,等待DS18B20将电平拉低。
TempBuf&=TANDMASK;
SP_Export(Port_IOB_Data,TempBuf);
HDM_DELAY_15us();
//将端口设置为悬浮式输入管脚
asm("%0=[P_IOB_Attrib]":"=r"(TempAttr));
asm("%0=[P_IOB_Dir]":"=r"(TempDir));
asm("%0=[P_IOB_Data]":"=r"(TempData));
TempDir&=TANDMASK;
TempAttr|=TORMASK;
TempData|=TORMASK;
SP_Init_IOB(TempDir,TempAttr,TempData);
}
//等待DS18B20反馈,当完成该反馈,证明DS18B20已经进入状态。
void ds18b20_presence()
{
unsigned int TempBuf;
while(1)
{
asm("%0=[P_IOB_Data]":"=r"(TempBuf));
if (!(TempBuf&SIGNALZERO))
break;
}
while(1)
{
asm("%0=[P_IOB_Data]":"=r"(TempBuf));
if (TempBuf&SIGNALZERO)
break;
}
HDM_DELAY_15us();
}
//从DS18B20读取一位数据
int ds18b20_read1bit()
{
unsigned int TempDir,TempAttr,TempData,TempBuf;
asm("%0=[P_IOB_Attrib]":"=r"(TempAttr));
asm("%0=[P_IOB_Dir]":"=r"(TempDir));
asm("%0=[P_IOB_Data]":"=r"(TempData));
TempDir|=TORMASK;
TempAttr&=TANDMASK;
TempData|=TORMASK;
SP_Init_IOB(TempDir,TempAttr,TempData);
HDM_DELAY_1us();
asm("%0=[P_IOB_Attrib]":"=r"(TempAttr));
asm("%0=[P_IOB_Dir]":"=r"(TempDir));
asm("%0=[P_IOB_Data]":"=r"(TempData));
TempDir&=TANDMASK;
TempAttr|=TORMASK;
TempData|=TORMASK;
SP_Init_IOB(TempDir,TempAttr,TempData);
HDM_DELAY_1us();
HDM_DELAY_1us();
HDM_DELAY_1us();
asm("%0=[P_IOB_Data]":"=r"(TempBuf));
if ((TempBuf&SIGNALZERO))
TempBuf=0;
else
TempBuf=1;
HDM_DELAY_15us();
HDM_DELAY_15us();
return TempBuf;
}
int ds18b20_read1Byte()
{
unsigned int i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=ds18b20_read1bit();
dat=(j<<7)|(dat>>1);
}
dat=~dat;
dat&=0x00ff;
return dat;
}
//写1,0是相互独立的写过程.在两个写过程之间应该有至少1个微秒的恢复时间.
//DS18B20在主机将电平拉下15us~60us之间对总线进行采样.
void ds18b20_write1Byte( int dat)
{
unsigned int i;
unsigned char j;
unsigned int testb;
unsigned int TempDir,TempAttr,TempData,TempBuf;
//初始化IOB0为输出端口,并输出1
asm("%0=[P_IOB_Attrib]":"=r"(TempAttr));
asm("%0=[P_IOB_Dir]":"=r"(TempDir));
asm("%0=[P_IOB_Data]":"=r"(TempData));
TempDir|=TORMASK;
TempAttr&=TANDMASK;
TempData&=TANDMASK;
SP_Init_IOB(TempDir,TempAttr,TempData);
for(j=1;j<=8;j++){
testb=dat&0x01;
dat=dat>>1;
HDM_DELAY_1us();
if(testb)
{
asm("%0=[P_IOB_Data]":"=r"(TempBuf));
TempBuf|=TORMASK;
SP_Export(Port_IOB_Data,TempBuf);
HDM_DELAY_1us();
HDM_DELAY_1us();
HDM_DELAY_1us();
HDM_DELAY_1us();
TempBuf&=TANDMASK;
SP_Export(Port_IOB_Data,TempBuf);
HDM_DELAY_15us();
HDM_DELAY_15us();
HDM_DELAY_15us();
}else {
asm("%0=[P_IOB_Data]":"=r"(TempBuf));
TempBuf|=TORMASK;
SP_Export(Port_IOB_Data,TempBuf);
HDM_DELAY_15us();
HDM_DELAY_15us();
HDM_DELAY_15us();
HDM_DELAY_15us();
TempBuf&=TANDMASK;
SP_Export(Port_IOB_Data,TempBuf);
}
}
}
void ds18b20Start()
{
unsigned int TempDir,TempAttr,TempData,TempBuf;
ds18b20_init();
ds18b20_presence();
Wait1ms();
ds18b20_write1Byte(SKIPROM);
ds18b20_write1Byte(CONVERTT);
asm("%0=[P_IOB_Attrib]":"=r"(TempAttr));
asm("%0=[P_IOB_Dir]":"=r"(TempDir));
asm("%0=[P_IOB_Data]":"=r"(TempData));
TempDir&=TANDMASK;
TempAttr|=TORMASK;
TempData|=TORMASK;
SP_Init_IOB(TempDir,TempAttr,TempData);
}
int ds18b20GetTemperature(void)//float *T)
{
unsigned int Lsb,Msb,Temp,Sign;
int T;
Sign=0;
ds18b20Start();
WaitNms(750);
ds18b20_init();
ds18b20_presence();
Wait1ms();
ds18b20_write1Byte(SKIPROM);
ds18b20_write1Byte(READSCRATCHPAD);
Lsb=ds18b20_read1Byte(); //LSB
Msb=ds18b20_read1Byte(); //MSB
Msb=Msb<<8;
if(Msb&0x8000) Sign=1;
Msb=Msb&0x0700;
Lsb=Lsb&0x00ff;
Temp=Msb|Lsb;
T=Temp/16;
if (Sign) T=-T;
return T;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -