|
STC15W4K56S4一线多点DS18B20问题
[复制链接]
#include
#include "stdio.h"
#include "intrins.h"
#define ulong unsigned long
#define uchar unsigned char
#define uint unsigned int
#define MAXNUM 5
#define MaxNum 4
sbit temp=P5^5; //18B20
uchar ID[4][8]={0};
uint wd;
float tt;
int num=0;
void UartInit(void) [url=]//9600bps@11.0592MHz[/url]
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE0; //设定定时初值
TH1 = 0xFE; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
TI= 1;
}
void Delay_DS18B20(ulong n)
{
while(n--);
}
/*****初始化DS18B20*****/
void Init_DS18B20(void)
{
unsigned char x=0;
temp = 1; //temp复位
Delay_DS18B20(2); //稍做延时4us
temp = 0; //单片机将temp拉低
Delay_DS18B20(90); //精确延时,大于480us
temp = 1; //拉高总线
Delay_DS18B20(20);
x = temp; //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
Delay_DS18B20(20);
}
/*****读一个字节*****/
unsigned char ReadOneChar(void)
{
unsigned char i=0,j=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
temp = 0; // 给脉冲信号
j++;j++; j++;j++;
dat>>=1;
j++;j++; j++;j++;
temp = 1; // 给脉冲信号
j++;j++; j++;j++;
if(temp)
dat|=0x80;
Delay_DS18B20(8);
}
return(dat);
}
/*********读一位***********/
//bit read1bit(void)
//{
// bit dat = 0;
//
// temp = 0; // 给脉冲信号
// Delay_DS18B20(1);
// temp = 1; // 给脉冲信号
// Delay_DS18B20(1);
// if(temp)
// dat|=0x01;
// Delay_DS18B20(5);
// return dat;
//}
/********读两位************/
unsigned char Read2Bit(void)
{
unsigned char i=0,j=0;
unsigned char dat = 0;
for (i=2;i>0;i--)
{
temp = 0; // 给脉冲信号
j++;j++; j++;j++;
dat<<=1;
j++;j++; j++;j++;
temp = 1; // 给脉冲信号
j++;j++; j++;j++;
if(temp)
dat|=0x01;
Delay_DS18B20(8);
}
return(dat);
}
//uchar Read2Bit(void)
//{
// uchar i,dat=0;
// for(i=0;i<2;i++)
// {
// dat<<=1;
// if(read1bit())
// dat|=1;
//
// }
//
// return dat;
//}
/*****写一个字节*****/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0,j=0;;
for (i=8; i>0; i--)
{
temp = 0;
j++;j++;j++;j++;
temp = dat&0x01;
Delay_DS18B20(10);
temp = 1;
dat>>=1;
j++;j++;j++;
}
}
/*********写一位*********/
void write_bit(unsigned char dat)
{
unsigned char i=0,j=0;;
for (i=1; i>0; i--)
{
temp = 0;
j++;j++;j++;j++;
temp = dat&0x01;
Delay_DS18B20(10);
temp = 1;
dat>>=1;
j++;j++;j++;
}
}
//void write_bit(unsigned char dat)
//{
//
// unsigned char i=0;
// for (i=1; i>0; i--)
// {
// temp = 0;
// temp = dat&0x01;
// Delay_DS18B20(10);
// temp = 1;
// Delay_DS18B20(10);
// }
//
// }
/*********************/
void Delay1000ms() [url=]//@11.0592MHz[/url]
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 43;
j = 6;
k = 203;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void tmpchange()
{
temp = 1;
Delay_DS18B20(5);
Init_DS18B20();
WriteOneChar(0xcc);
WriteOneChar(0x44);
Delay_DS18B20(20000);
}
/*
uchar search_rom(void)
{
unsigned char k,l,chongtuwei,m,n;
unsigned char zhan[(MAXNUM)]={0};
unsigned char ss[64];
int num = 0;
l=0;
do
{
Init_DS18B20();
Delay_DS18B20(100);
WriteOneChar(0xf0);
Delay_DS18B20(100);
for(m=0;m<8;m++)
{
unsigned char s=0;
for(n=0;n<8;n++)
{ t1=0;
t2=0;
t3=0;
k=Read2Bit();//读两位数据
k=k&0x03;
s>>=1;
if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应
{ t1=1;
write_bit (0);
ss[(m*8+n)]=0;
}
else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应
{ t2=1;
s=s|0x80;
write_bit (1);
ss[(m*8+n)]=1;
}
else if(k==0x00)//00,判断冲突位 冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写1
{ t3=1;
chongtuwei=m*8+n+1;
if(chongtuwei>zhan[l])
{
write_bit (0);
ss[(m*8+n)]=0;
zhan[++l]=chongtuwei;
}
else if(chongtuwei
{
s=s|((ss[(m*8+n)]&0x01)<<7);
write_bit (ss[(m*8+n)]);
}
else if(chongtuwei==zhan[l])
{
s=s|0x80;
write_bit (1);
ss[(m*8+n)]=1;
l=l-1;
}
}
else
{
return num; //搜索完成,//返回搜索到的个数
}
}
ID[num][m]=s;
}
num=num+1;
}
while(zhan[l]!=0&&(num
return num; //返回搜索到的个数
}
*/
uchar search_rom()
{
uchar k,l=0,chongtuwei,m,n,a;
uchar _00web[MAXNUM]={0};
do
{
Init_DS18B20();
WriteOneChar(0xf0);
for(m=0;m<8;m++)
{
char s=0;
for(n=0;n<8;n++)
{
k=Read2Bit();//读两位数据
k=k&0x03;
s>>=1;
if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应
{
write_bit(0);
}
else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应
{
s=s|0x80;
write_bit(1);
}
else if(k==0x00)//读到的数据为00 有冲突位 判断冲突位
{ //如果冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写1
chongtuwei=m*8+n+1;
if(chongtuwei>_00web[l])
{
write_bit(0);
_00web[++l]=chongtuwei;
}
else if(chongtuwei<_00web[l])
{
a=(ID[num-1][m]>>n)&0x01;
s=s|(a<<7);
write_bit(a);
}
else if(chongtuwei==_00web[l])
{
s=s|0x80;
write_bit(1);
l=l-1;
}
}
else if(k==0x03)
{
return (0);
}
}
ID[num][m]=s;
}
num++;
}
while((_00web[l]!=0)&&(num
return (1);
}
void tmp(uchar i)
{
uchar a,b,f;
Init_DS18B20();
Delay_DS18B20(1);
WriteOneChar(0x55); //匹配
for(f=0;f<8;f++)
{
WriteOneChar(ID[f]); //发匹配rom
printf("%02x\r\n",ID[f]);
}
Delay_DS18B20(15);
WriteOneChar(0xbe);
Delay_DS18B20(15);
a=ReadOneChar();
b=ReadOneChar();
wd=b;
wd<<=8;
wd=wd|a;
if((wd&0xf800)==0xf800)
{
wd=~wd+1;
tt=wd*0.625+0.5;
tt=tt*(-1);
}
else
{
tt=wd*0.625+0.5;
}
}
void main()
{
uchar i;
search_rom();
UartInit();
printf("num=%d\r\n",num);
//
while(1)
{ tmpchange();
for(i=0;i
{
tmp(i);
printf("temp=%f\r\n",tt);
}
Delay1000ms();
// Init_DS18B20();
// WriteOneChar(0xCC); //跳过读序号列号的操作
// WriteOneChar(0x44); //启动温度转换
// Delay_DS18B20(20);
// Init_DS18B20();
// WriteOneChar(0xCC); //跳过读序号列号的操作
// WriteOneChar(0xBE); //读取温度寄存器
// a=ReadOneChar(); //读低8位
// b=ReadOneChar(); //读高8位
// t=b;
// t<<=8;
// t=t|a;
// if((t&0xf800)==0xf800)
// {
// t = ~t;
// t = t + 1;
// flag = 1;
// tt=t*0.0625*10 + 0.5;
// tt=tt*(-1);
// }
// else
// {
// tt = t*0.0625*10 + 0.5;
// }
// printf("temp = %.1f\r\n",tt/10);
// Delay1000ms();
}
}
调试了很长时间,一直出不来,获取ROM序列号的时候存在问题,单个DS18B20能正常读取温度,连上多个之后就不行了,大神们帮帮忙~~~
|
|