本人是个新手,大家别笑话。 这个DS18B20驱动程序我写了1星期,参考例程数据手册改了很多次就是没用,甚至还用protues示波器观察仿真波形都没问题,大家能帮我看一下错哪了吗?下面是DS18B20的代码
/******************************************************************************* *
* DS18B20.h *
* *
******************************************************************************
描述: 的头文件
硬件:
******************************************************************************/
#ifndef DS18B20_H
#define DS18B20_H
#include <STC12C5A60S2.H>
//#include <STC89C5xRC.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//unsigned char data RomCode[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//存储序列号
unsigned char Temp;
unsigned char crc;
sbit DQ=P2^4;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
struct Temperature
{
uchar LSB;
uchar MSB;
uint temper; // 温度的2进制存储格式
uchar flag; // 负号标志
float f_temper; //温度的浮点数存储格式
uchar cc; //整数
uchar xs; //1位小数
} temperature={0,0,0,0,0.0,0,0};
/***********************函数声明区**************************************************/
/***********************函数定义区**************************************************/
/******************************************************************
函数名:微秒级延时函数
调用:
参数:
返回值:
功能:
备注:
******************************************************************/
void Delayxus(unsigned int j) //延时(j+1)*15us
{
//CLK_DIV=0x03; //用于stc12系列高速单片
for(j;j>0;j--)
{
_nop_();_nop_();_nop_();_nop_();
}
_nop_(); _nop_();
//CLK_DIV=0x00;
}
/******************************************************************
函数名:DS18B20复位函数
调用:
参数:
返回值:
功能:
备注:
******************************************************************/
bit DS18_init()
{
bit presence;
EA=0;
DQ = 1; //DQ复位
Delayxus(1); //稍做延时
DQ = 0; //将DQ拉低
Delayxus(32); //精确延时 大于 480us
DQ = 1; //拉高总线
Delayxus(3); //60
presence = DQ; //读取存在信号
Delayxus(32);
DQ = 1;
return(presence); //返回信号,0=presence,1= no presence
EA=1;
}
/******************************************************************
函数名:读1位函数
调用:
参数:
返回值:
功能:
备注:
******************************************************************/
unsigned char DS18_readbit(void)
{
bit dat;
// unsigned char i;
EA=0;
DQ=1;
_nop_();
DQ=0; //将DQ 拉低开始读时间隙
_nop_();
DQ=1; //释放总线
_nop_();
_nop_();
dat=DQ; // then return high
Delayxus(3); // 延时60μs
DQ=1;
EA=1;
return(dat); // 返回 DQ 线上的电平值
}
/******************************************************************
函数名:写1位函数
调用:
参数:
返回值:
功能:
备注:
******************************************************************/
void DS18_writebit(unsigned char dat)
{
EA=0;
DQ = 0;
_nop_();
_nop_(); // 将DQ 拉低开始写时间隙
if(dat==1)
DQ =1; // 如果写1,DQ 返回高电平
Delayxus(4); // 在时间隙内60保持电平值,
DQ = 1;
EA=1;
}
/******************************************************************
函数名:读1字节函数
调用:
参数:
返回值:
功能:
备注:
******************************************************************/
unsigned char DS18_readbyte(void)
{
unsigned char i = 0;
unsigned char dat = 0;
for (i=0;i<8;i++)
{ // 读取字节,每次读取一个字节
if(DS18_readbit())
dat|=0x80; // 然后将其左移
dat>>=1;
}
return (dat);
}
/******************************************************************
函数名:写1字节函数
调用:
参数:
返回值:
功能:
备注:
******************************************************************/
void DS18_writebyte(unsigned char dat)
{
unsigned char i = 0;
unsigned char temp;
for (i=0; i<8; i++) // 写入字节, 每次写入一位
{
temp=0x01&dat;
DS18_writebit(temp);
dat>>=1;
}
}
/******************************************************************
函数名:温度转换启动函数
调用:
参数:
返回值:
功能:
备注:
******************************************************************/
void DS18_CONVERT()
{
bit prese; //返回校验位
/*************启动温度转换****************/
prese=DS18_init();
DS18_writebyte(0xcc);
DS18_writebyte(0x44);
return prese;
}
/******************************************************************
函数名:DS18B20获取温度函数
调用:
参数:
返回值:
功能:
备注:
******************************************************************/
void DS18_GET()
{
bit prese;//返回校验位
/*************获取温度****************/
prese=DS18_init();
DS18_writebyte(0xcc);
DS18_writebyte(0xbe);
temperature.LSB=DS18_readbyte();
temperature.MSB=DS18_readbyte();
/*************数据处理部分****************/
temperature.temper=temperature.MSB&0x07;
temperature.temper<<=8;
temperature.temper=temperature.temper|temperature.LSB;
if(temperature.MSB>0xf8)
temperature.flag=1; //负号标志置1
temperature.f_temper=temperature.temper/16;
temperature.cc=(uchar)temperature.f_temper;
temperature.xs=(uchar)(temperature.f_temper*10);
temperature.xs=temperature.xs%10;
}
/******************************************************************
函数名:DS18B20获取ROM函数
调用:
参数:
返回值:
功能:
备注:
******************************************************************
void Read_RomCord(void)
{
unsigned char j;
DS18_init();
DS18_writebyte(0x33); // 读序列码的操作
for (j = 0; j < 8; j++)
{
RomCode[j] = DS18_readbyte();
}
}
/******************************************************************
函数名:
调用:
参数:
返回值:
功能:
备注:
******************************************************************
uchar CRC8()
{
uchar i,x; uchar crcbuff;
crc=0;
for(x = 0; x <8; x++)
{
crcbuff=RomCode[x];
for(i = 0; i < 8; i++)
{
if(((crc ^ crcbuff)&0x01)==0)
crc >>= 1;
else {
crc ^= 0x18; //CRC=X8+X5+X4+1
crc >>= 1;
crc |= 0x80;
}
crcbuff >>= 1;
}
}
return crc;
}
/***********************************************************/
#endif
|